PageCache caching uncacheable responses (violating HTTP/1.0 spec) + D8 intentionally disabling HTTP/1.0 proxies = WTF

Created on 13 December 2016, over 7 years ago
Updated 3 April 2024, 10 days ago


PageCache determines which responses to cache by inspecting the Expires header. (This should be updated to use the Cache-Control header instead, but that's out of scope here.)

Responses that have Expires: Sun, 19 Nov 1978 05:00:00 GMT are meant to not be cached, because it's an expiration date in the past. Yet PageCache caches them permanently:

$expire = ($date > $request_time) ? $date : Cache::PERMANENT;

This has been the case for a very long time, even predating #2527126: Only send X-Drupal-Cache-Tags and -Contexts headers when developer explicitly enables them β†’ . Quite possibly the rationale was .

Now, to make matters worse, even when you configure a non-zero "max age" at /admin/config/development/performance, \Drupal\Core\EventSubscriber\FinishResponseSubscriber::setResponseCacheable() will still cause that same Expires header to be set? Why? Because when \Drupal\Core\EventSubscriber\FinishResponseSubscriber::onRespond() calls \Drupal\Core\EventSubscriber\FinishResponseSubscriber::setResponseCacheable(), the latter contains this code:

    // HTTP/1.0 proxies do not support the Vary header, so prevent any caching
    // by sending an Expires date in the past. HTTP/1.1 clients ignore the
    // Expires header if a Cache-Control: max-age directive is specified (see
    // RFC 2616, section 14.9.3).
    if (!$response->headers->has('Expires')) {

In other words:

  1. Drupal 8 intentionally disables HTTP/1.0 proxies
  2. Drupal 8 ships with a HTTP/1.0 reverse proxy that is breaking the spec: Page Cache

Proposed resolution

Make \Drupal\page_cache\StackMiddleware\PageCache a HTTP/1.1 proxy: make it inspect Cache-Control rather than Expires

Remaining tasks


Remaining tasks


User interface changes


API changes


Data model changes


πŸ› Bug report

Needs work


11.0 πŸ”₯

Page cacheΒ  β†’

Last updated 10 days ago

Created by

πŸ‡§πŸ‡ͺBelgium Wim Leers Ghent πŸ‡§πŸ‡ͺπŸ‡ͺπŸ‡Ί

Live updates comments and jobs are added and updated live.
  • DrupalWTF

    Worse Than Failure. Approximates the unpleasant remark made by Drupal developers when they first encounter a particular (mis)feature.

  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates : some issue and comment data are missing.

Production build 0.62.1