Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm using Apache 2.4.3 as a reverse proxy due to it's advertised compliance with RFC 2616. My app uses headers like this to enable caching at the proxy:

Cache-Control: public, s-maxage=0
Expires: ... (+1 day)
X-Group: A
Vary: X-Group
ETag: W/"foo1"

After the first request warms the cache, if my app changes to respond with this:

Cache-Control: public, s-maxage=0
Expires: ... (+1 day)
X-Group: B
Vary: X-Group
ETag: W/"foo2"

The app will respond with 304 Not Modified if the If-None-Match header from Apache matches the origin-generated ETag. However, Apache then caches the second 200 response and replaces the "foo1" record with the new response instead of caching both of the responses with different ETags. Therefore, instead of If-None-Match: W/"foo1", W/"foo2" the next revalidate request is just If-None-Match: W/"foo2". So the cache is constantly getting misses instead of always getting hits.

From the RFC 2616 section 12.1:

However, an origin server is not limited to these dimensions and MAY vary the response based on any aspect of the request, including information outside the request-header fields or within extension header fields not defined by this specification.

I've tried the following combinations for Vary:

Vary: X-Foo
Vary: *
Vary: User-Agent

I've also tried both strong and weak ETags and no matter what I cannot get Apache to cache the two responses simultaneously, it always saves over the previous one. If it can't save more than one variance of a page then ETag is useless, Last-Modified would be just as good.

From the Apache 2.4 docs:

mod_cache implements an RFC 2616 compliant HTTP content caching filter, with support for the caching of content negotiated responses containing the Vary header.

Note that it says "responses" plural. Am I mis-interpreting the HTTP spec or does Apache 2.4 just not fully support ETags after-all?

share|improve this question
Sounds like you need to go here. – Michael Hampton Dec 22 '12 at 20:08
up vote 1 down vote accepted

You give a couple of examples like this:

Cache-Control: public, s-maxage=0
Expires: ... (+1 day)
X-Group: A
Vary: X-Group
ETag: W/"foo1"

I notice in particular the Vary: X-Group header. Is X-Group a request header or a response header?

As per RFC 2616 section 14.44, Vary should list any request headers that will result in a different content representation from an origin server. From your example, I suspect X-Group might be a response header, in which case mod_cache won't be storing multiple versions of the given resource.

One thing you could try would be to set Vary: If-None-Match, which would let mod_cache store a version of the resource for each ETag. Admittedly, I haven't tried this. Assuming it works, one downside is that the first request from any client would be a cache miss.

share|improve this answer
You're right, I was mixing up requests/responses.. Still I found that Vary had no effect and the cache apparently only stores the latest version for a given url. – ColinM Mar 10 '14 at 21:35

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.