Problem/Motivation
Files from a module lower in the module discovery hierarchy may wrongly be in use, due to APCu caches not getting cleared. (Is there a drupal.org documentation page which explains how the module discovery hierarchy works?)
It is currently a bit tedious to clear the APCu cache, which can be necessary, for example after switching from using a deprecated Drupal core module (for example Forum) to its new contrib counterpart.
But the tediousness of the process is a minor factor, and there's a much bigger problem:
Users who run into this problem, may spend quite a long time trying different things and failing. Only after spending even more time searching for a solution via the search engines, Drupal forum, etc., they might find the tricky solution.
So getting to the bottom of this, both understanding the source of the problem, and fixing it can eventually save many users a lot of time.
Note: After rebuilding caches via the browser or Drush, contrib Forum 1.0.2 version of the module (modules/contrib/forum) may be listed on the Extend page, as the only Forum module, even while files used are from Drupal core Forum version (core/modules/forum).
UPDATE, Oct 2025: See also @apotek's deep analysis in Drush cache:rebuild does not completely rebuild cache like rebuild.php or admin/config/development/performance "clear all caches" does #6406.
Workarounds via settings.php: class_loader_auto_detect, deployment_identifier, or rebuild_access
-
One workaround is to clear the APCu cache, by adding this in
settings.phpand rebuild caches:$settings['class_loader_auto_detect'] = FALSE;From https://www.drupal.org/docs/administering-a-drupal-site/troubleshooting-...
-
Another workaround is to change the deployment identifier, by adding this in
settings.phpand rebuild caches, which works equally well (the value can be anything, as long as it changes):$settings['deployment_identifier'] = "forum_102"; -
A third option is adding this in
settings.phpand visit/core/rebuild.php:$settings['rebuild_access'] = TRUE;
If Composer cleared APCu caches when Drupal core version changes, or when contrib modules are added or removed (basically any time composer.lock changes), it could update stale module paths and #3509069: Use a better container cache key may enable this.
Still, actually clearing all caches, by also clearing APCu with the standard method, would be great.
Another case, where it's difficult to clear all the relevant caches is #3050261: index.php randomly appears in friendly URLs. It seems that the "Clear all caches" UI button works better than Drush.
Steps to reproduce
- Create a fresh Drupal installation with DDEV
- To check if the Core module is used, tweak a line in
core/modules/forum/src/Controller/ForumController.phpto this:
'title' => $this->t('CORE -- Add new @node_type', [ - Install the Drupal core Forum module
- Rebuild caches -- this one is important, to populate the caches, otherwise you might not see the stale caches at the end of the process:
drush cache:rebuild - Check under
/forum/1that it says "CORE -- Add new Forum topic" - Download its contrib version with Composer:
composer require drupal/forum - Rebuild caches:
drush cache:rebuild - Expect
modules/contrib/forumto be used, beforecore/modules/forumbut see that the files from the old core module may still be used -- it still says "CORE -- Add new Forum topic" - Add
$settings['class_loader_auto_detect'] = FALSE;insettings.phpand rebuild caches - See that files from
modules/contrib/forumare now used, it says "Add new Forum topic"
Reliably reproduce stale cache behaviour
Use this method to reliably reproduce the above behaviour, again and again, and tweak the "Add new" text, to track if cache is stale:
1. SET UP Drupal 11
ddev config --project-type=drupal11 --docroot=web
ddev start
ddev composer create drupal/recommended-project
ddev composer require drush/drush
git clone https://git.drupalcode.org/project/forum web/core/modules/forum
sed -i "s|Add new|CORE -- Add new|g" web/core/modules/forum/src/Controller/ForumController.php
drush site:install -y
Check that it says "CORE -- Add new" under /forum/1.
2. REPEAT THIS after each try, for a fresh start:
ddev composer remove drupal/forum && \
ddev delete --omit-snapshot -y && \
ddev start && \
drush site:install -y && \
drush install forum && \
xdg-open $(drush uli forum/1)
Important step! Rebuild caches, to populate them:
ddev drush cache:rebuild <<<<<<< This cache rebuild makes all the difference
3. Download Forum and rebuild caches
Download Contrib forum, rebuild caches and check in browser
ddev composer require drupal/forum
ddev drush cache:rebuildThe text is still "CORE -- Add new [...]", should be just "Add new [...]" ...
Proposed resolution
It would fix the challenge of updating stale module paths, if Composer cleared APCu caches when composer.lock changes. Though, being able to clear all caches (including APCu) manually would be a great feature ... so maybe both tasks should be pursued.
- Actually clear all caches, including APCu, when clicking "Clear all caches"
The button says "Clear all caches" on the "Performance" page at
/admin/config/development/performance, so when a user clicks it -- or runsdrush cache:rebuild-- it is reasonable to expect that all caches are actually cleared.Could a more efficient method be used, something similar to running
/core/rebuild.php, which clears all caches? ... or simply makerebuild.phpthe default method?For edge cases such as multisite installations, where one site clearing the APCu cache would in effect clear it for all for multi-sites, there could be a "Keep APCu cache" setting on the "Performance" page (
/admin/config/development/performance), or simply just support for a$settings['keep_apcu_cache'] = TRUE;insettings.php? -
Add a built-in secrets system for
/core/rebuild.php, same as for CronAlternatively, make it easier to clear all caches, including APCu, by performing a "one step" action, such as visiting an URL in the browser, where the unique token prevents outsiders from running it, like with Cron:
https://example.org/core/rebuild-caches/s5sWtcux_ddf22[...], but ideally, the standard method to clear cache should be fixed.Adding such a built-in secrets system for
/core/rebuild.php, like Drupal core does for cron requests would allow Drush integration. @weitzman:Drush isnt going to hit rebuild.php until core provides a built-in secrets system for it like it does for cron requests.
... and also in Clear user caches like core/rebuild.php does. #2450:
If Drupal provides some endpoint on the web that we can hit to clear APCU et al for the webserver, that would be ideal.
- Clear all caches, also APCu, if
composer.lockchangesIdeally, Composer should clear the APCu cache, after a project is added or removed:
Shouldn't Composer clear the apcu cache whenever the composer.lock hash changes?
From #3492523-41: Class "Doctrine\Deprecations\Deprecation" not found.
from the Composer issue Package of version 1.1.4 is missing the lib folder #72:
If you enable Composer's APCu autoloader, then yes, you could clear the APCu cache when installing dependencies.
#3509069: Use a better container cache key may enable this.
Comments
Comment #2
ressaComment #3
ressaConnecting the issue which triggered this issue.
Comment #4
cilefen commentedDoes changing the deployment identifier fix this situation? It may not. Even if it does, this feature may be helpful.
Comment #5
ressaThanks for the link @cilefen. I am not sure if it could help. Like, how do you suggest it should be used to solve the task outlined in this issue?
My aim is to make it easier to clear all caches without editing
settings.php, but simply by visiting an URL, or some other "one step" action, like clicking a button, issuing a command on the CLI, etc. and I have updated the Issue Summary to make this clearer.I found a comment in another issue #3492523-41: Class "Doctrine\Deprecations\Deprecation" not found which looks really interesting:
That would take care of the stale paths after switching from a core to a contrib module, since
composer.lockwill have changed.Comment #6
ressaAdding Composer issue about APCu cache.
Comment #7
ressaMention #3509069: Use a better container cache key in the Issue Summary.
Comment #8
cilefen commentedThe reason I asked because switching the deployment identifier "fixes moved class autoloader caching". According to what I've read it is an underused configuration so in the context of evaluating the value of this feature request I thought more information would add context.
Does browsing
core/rebuild.phpalso do this? I think it runsapcu_clear_cache. Again, this is only to get more information.Comment #9
ressaFirst of all, I need to emphasize, that I am extremely grateful for your fast and investigative questions, I feel quite privileged.
So I am sorry if I sounded irritated, when I asked the question, which I am definitely not -- I just don't know anything at all about the inner workings of Composer, Symfony, autoloaders, etc. since I am not a developer, but a simple site builder.
My approach here is trying to report down from the Drupal trenches, trying as best as I can to investigate, and try out different things, in an actual "regular user" scenario (i.e. using recommended project in DDEV with plain vanilla settings, meaning default caching, no configuration tweaks, etc.)
So when I asked "Like, how do you suggest ...", my point was simply this:
How does this new method in actual effect differ from adding
$settings['class_loader_auto_detect'] = FALSE;insettings.php? Because editingsettings.phpis what I want to avoid ...But it's interesting :) So I have now tried adding a dummy
$settings['deployment_identifier'] = "forum_102";insettings.phpand rebuilding caches, and it works equally well as settingclass_loader_auto_detect, so now there are two methods.core/rebuild.phporupdate.phpdo not clear cachesBrowsing
core/rebuild.phpnorupdate.phpclears the caches, and so far onlyclass_loader_auto_detectordeployment_identifierinsettings.phphas worked.UPDATE, Oct 2025:
/core/rebuild.phpdoes work, if you add$settings['rebuild_access'] = TRUE;insettings.php.Also, I have noticed that after getting everything set up for test, you need to rebuild the caches while the core (or original module) is the only one present, before proceeding with downloading contrib version and clearing caches -- I guess to populate the caches?
Otherwise, you might check the
/forum/1path, download contrib, clear cache, and then contrib code will be in effect.I have updated the Issue Summary with a reproducible method, which yields the same stale caches result every time. I first tried using DDEV's snapshots feature, but it looked like the caches were not totally emptied.
Perhaps you can give it a shot, and check if you see the same thing that I do? Feel free to ask, if anything in the process is unclear.
Comment #10
ressaComment #11
mdyoung3 commentedHi,
I followed the steps outlined above and replicated the issue. Adding `$settings['class_loader_auto_detect'] = FALSE;` does indeed fix the issue.
I suspect the ACPu prefix changes with`$settings['deployment_identifier'] = "forum_102";` because it forces the creation of a new prefix: https://github.com/drupal/drupal/blob/a2b731f0c8212ecddad9b9caffa0b69cc6...
Comment #12
ressaThanks for going through with the steps and replicating it @mdyoung3, it's really great to get a confirmation.
Comment #13
mdyoung3 commentedHey Ressa,
I see you. I've been bitten by this issue in the past. It can be infuriating. I'd like to see Drupal be more friendly to upgrades as possible.
I've been reviewing the various parts that deal with APCu caching and i don't think it's a good idea to change the prefix hash each time composer.lock file is updated: https://www.drupal.org/project/drupal/issues/2926309
But I do like the idea of having another method for updating the prefix. Maybe a drush command and/or a button in the Admin UI to recreate it.
Comment #14
ressaYes @mdyoung3, and even for seasoned Drupal users such as you and I, and probably many others, it's a real challenge to figure out how to _really_ clear the caches. Imagine what a stumbling block it could be for a new Drupal user? This is why I think it's a very important task to solve.
Thanks for the link to the other epic APCu issue, I have added it as related to connect the issues.
I am not a programmer, so I have no opinion about the right code, but the 2 solutions so far in the Issue Summary were:
This one may be taken care of in #3509069: Use a better container cache key and will take care of old caches, when updating a module
... but instead of adding a new, special method to clear all caches, maybe the second proposed solution should instead be this?
Do you know if there is a technological reason for this not to be the case now?
I have updated the Issue Summary, but in case it's impossible to make the "Clear all caches" button clear all caches, I will of course revert to the previous suggestion, of introducing an extra cache-clearing method, to take care of the APCu cache.
Comment #15
ressaAdding another issue with a cache clearing challenge. It seems that the "Clear all caches" UI button works better than Drush.
Comment #16
ressaAdding link to Github issue Drush cache:rebuild does not completely rebuild cache like rebuild.php or admin/config/development/performance "clear all caches" does #6406 in Issue Summary, thanks @apotek :)
Comment #17
ressa@cilefen: I have just now realized, that for
/core/rebuild.php(https://api.drupal.org/api/drupal/core%21rebuild.php/11.x) to work, you need to add$settings['rebuild_access'] = TRUE;insettings.php, and then it works well.Note to myself: It is not included in default.settings.php, only in example.settings.local.php.
Comment #18
ressaUpdating "Proposed resolution".
Comment #19
ressaI think I had an encounter with this problem in #3565117: Some Details links give Page not found .Probably not, I am not sure :)Comment #20
bkosborneYou mentioned that changing the deployment identifier resolves the issue for you, right? That's likely because the deployment identifier is used in the cache key prefix for things that utilize the APCu cache (like composer's class map) and various FileCache usages (things that scan files on disk). This in effect causes a cache bust of the APCu cache entries (without clearing out everything that's in there).
You should be changing the deployment_identifier when updating the code. I agree it's not well known or documented: #3153335: Document $settings['deployment_identifier'] (and that it fixes moved class autoloader caching).
I don't think having a Drupal cache clear also clear the APCu cache would be wise. That would negatively affect multisite installations as they all use APCu. If one site cleared the APCu cache, it would in effect clear it for all sites.
Comment #21
ressaThanks for sharing extra information about the internal structure @bkosborne -- and yes, that is one of the three workaround methods I listed in the Issue Summary.
So I know that it exists, but my whole point is that the majority of users (especially those just getting started) should not have to use workarounds for something you expect as a user:
When you click "Clear cache", all caches should be cleared, and you should get a clean slate.
You mention multisite, and for multisite installations, I think conversely, that the default ought to be a total cache clear, since 99% of installations are not multisite installations (I have added it under "Proposed resolution"):
/admin/config/development/performance), or simply just a$settings['keep_apcu_cache'] = TRUE;insettings.php?What do you think about that?
Comment #23
lambert commentedFor a simple sitebuilder like me, Drupal makes many things easy, but there are some things that should be easy that are in fact hard.
A button that says "Clear all caches" that does not, in fact, clear "all" caches is one of those hard things[1].
If we can't make the button do what it says it does, can we either change the name of the button ("Clear most caches"), and/or add a description of what caches it actually does clear?
NOTE
[1] Worse, it's deceptive, so there's a reputational issue involved beyond the UI/UX.