Repository navigation
Fast 404 answers missing image style derivatives with a 404 for every user, so they're never generated #3211
Description
Summary
web/sites/default/includes/modules/settings.fast_404.php sets fast404_allow_anon_imagecache to FALSE. With drupal/fast_404 3.7.0, that answers every request for a missing public png, gif or jpg image style derivative with the fast 404, for anonymous and logged-in users alike. Drupal only generates a derivative when its URL is first requested, so on a site with this setting derivatives are never generated: newly uploaded images, new image styles and everything after an image style flush render broken.
1.42.0 is the first release where this applies. #3101 fixed the settings guard and started shipping drupal/fast_404 (on by default in new installs; existing projects get it only when they require the package), and #3102 set the value to FALSE. In 1.41.1 the guard checked a path Composer never creates, so the handler never ran.
Details
Cause
For a path that contains styles/, Fast404::extensionCheck() is meant to let logged-in users through when it finds a session cookie:
$cookies = $this->request->cookies->all();
// At this stage of the game we don't know if the user is logged in via
// regular function calls. Simply look for a session cookie. If we find
// one we'll assume they're logged in.
if (isset($cookies) && is_array($cookies)) {
foreach ($cookies as $cookie) {
if (stristr($cookie, 'SESS')) {
return;
}
}
}cookies->all() returns cookie names mapped to values, and the loop only looks at the values. Drupal puts SESS in the cookie name (SESS<hash>, or SSESS<hash> over HTTPS), while the value is a random session ID, so the exception never matches. The request falls through to the fast404_exts check, which matches .png, .gif and .jpg.
Private files under /system/files and WebP-converted styles aren't affected, because the extension pattern doesn't match them.
Reproduction
Running the module's Fast404 class with the shipped settings against /sites/default/files/styles/large/public/2026-10/photo.jpg, once with no cookies and once with a SSESS<hash> session cookie:
fast404_allow_anon_imagecache |
Anonymous | Logged in |
|---|---|---|
FALSE |
blocked (404) | blocked (404) |
TRUE |
passed to Drupal | passed to Drupal |
Fast404::isPathBlocked() always returns FALSE under the CLI SAPI, so a command-line check has to read the respond404 property instead. On a provisioned site, upload an image, then request one of its derivative URLs logged out and logged in.
subtestAhoyFast404() in .vortex/tests doesn't catch this, because it requests a derivative of a source image that doesn't exist, which returns a 404 either way.
Fix options
- Set
fast404_allow_anon_imagecachetoTRUE, the module default and the value its README shows. Missing derivatives then reach Drupal, which already rejects derivative URLs without a validitoktoken by default. The change also needs the 17 expectations intests/phpunit/Drupal/EnvironmentSettingsTest.phpandtests/phpunit/Drupal/SwitchableSettingsTest.php, the derivative assertions insubtestAhoyFast404(), and the Fast 404 settings list in.vortex/docs/content/development/modules/contributed-modules.mdx, followed byahoy update-snapshots. - Keep
FALSEand patch the module to matchSESSagainst cookie names. Logged-in users could then generate derivatives, but anonymous visitors would still get broken images for any derivative that nobody logged in has triggered yet.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsReleased in 1.42.0
Activity
[#3211] Fixed Fast 404 blocking missing image style derivatives by se…