I'm scratching my head a bit on this. A Drupal site I run is setting appropriate cache headers that should indicate that the page can be cached for 15 minutes. However, every time I hit the page it always sends a GET request instead of loading the page from the cache.

I'm not forcefully refreshing the page each time, which I assume would indicate to the browser I want to flush the caches. I don't have any developer mode cache busting enabled.

Is this just the default behavior of browsers, or am I missing something obvious? Here's the request/response headers from hitting my homepage from FireFox dev tools:

NOTE/EDIT: Some people have suggested this was related to the Expires header being in the past. However Cache-Control overrides anything in Expires, as described in RFC 2616, Sec 14.9.3. Drupal includes this to disable caching on older HTTP 1.0 clients, which don't support the more advanced Vary header that Drupal needs for proper caching.

enter image description here

3 Answers 3


You have a Vary: Cookie,Accept-Encoding header in the response. That pretty much means that if the proxy (including your browser) wanted to cache this page it should be prepared to cache a new version for every possibly modified cookie vlaue (or changs in accept-encoding). Especially, it would have to keep a record in the first place of the cookies as they where sent in the request as a distinguishing criterion. I can imagine that either the browser denies this if the cookie is too large (and hence unlikely to be repeate), or it denies it i order to avoid cookie information being leaked via the cache content, or simply the cookie content gets changed on every call.

  • 4
    Was JUST about to answer my own question as I came to this conclusion as well. I have Google Analytics cookies, one of which changes on each page request, preventing the page from being cached.
    – Brian
    Commented May 16, 2014 at 18:31

In CMS programs some pages require interaction with the database to display the dynamic content specific to the users request. The entire page can't be cached or it wouldn't show the correct content to the user.

An example of this in practice is an eCommerce shopping cart / checkout page. Since the page looks different every time there's no way to cache it fully. Without knowing more about the specific page it's difficult to know if the page you are referencing requires database involvement.

  • While that's true, that is not true of Drupal's page caching mechanism (it literally caches the entire HTML output and delivers it for "anonymous" traffic) and not really related to my question. My question is about how browsers seem to react incorrectly to the appropriate page cache headers that are set (see the image).
    – Brian
    Commented May 16, 2014 at 15:30
  • I've seen this before during debugging, but can't remember, is there a valid reason your response header shows Expires: Nov 1978? Or that may be your answer.
    – JMC
    Commented May 16, 2014 at 15:49
  • 1
    In Drupal's code, the comment above that header reads: "HTTP/1.0 proxies does not support the Vary header, so prevent any caching by sending an Expires date in the past. HTTP/1.1 clients ignores the Expires header if a Cache-Control: max-age= directive is specified (see RFC 2616, section 14.9.3)." The date specifically is creator of Drupal's birthday.
    – Brian
    Commented May 16, 2014 at 16:45
  • It is still weird that the Expires does not match e.g. Last-modified plus max-age Commented May 16, 2014 at 18:31

In addition to the other answers, the Expires header is in the past, that is also one reason browsers won't cache the page.

  • This is not true when when a Cache-Control header is present. It overrides the Expires header for HTTP 1.1 clients. See ietf.org/rfc/rfc2616.txt, section 14.9.3.
    – Brian
    Commented May 20, 2014 at 12:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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