Problem/Motivation
We were investigating enabling Redis caching for Drupal 8 out of the box on Platform.sh. However, when I tried to install Drupal with the Redis module already configured the first load of the actual site offers a fatal error with the generic "The website encountered an unexpected error. Please try again later."
Rerunning the installer with debug output set to verbose offers this error output:
The website encountered an unexpected error. Please try again later.
InvalidArgumentException: No check has been registered for access_check.permission in Drupal\Core\Access\CheckProvider->loadCheck() (line 97 of core/lib/Drupal/Core/Access/CheckProvider.php).
Drupal\Core\Access\AccessManager->performCheck('access_check.permission', Object) (Line: 135)
Drupal\Core\Access\AccessManager->check(Object, Object, Object, 1) (Line: 112)
Drupal\Core\Access\AccessManager->checkRequest(Object, Object, 1) (Line: 107)
Drupal\Core\Routing\AccessAwareRouter->checkAccess(Object) (Line: 92)
Drupal\Core\Routing\AccessAwareRouter->matchRequest(Object) (Line: 154)
Symfony\Component\HttpKernel\EventListener\RouterListener->onKernelRequest(Object, 'kernel.request', Object) (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch('kernel.request', Object) (Line: 125)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 64)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 50)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 656)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
Oddly, the first time (without verbose debugging) a page reload worked and gave me an installed site. With verbose debugging enabled a reload just gives me the same error message. If I run "drush cr" manually then the site comes up and appears to function correctly thereafter.
The install process itself seemed to have no error either way. It's just after redirecting to the actual site that the error appears.
Since a force cache rebuild fixes it, my suspicion is that it's caused by a cache not being "Ready" in time to be populated and the particular access check it fails is simply the first of a certain cache lookup rather than itself the buggy component.
Proposed resolution
¯\_(ツ)_/¯
Comments
Comment #2
Crell commentedComment #3
berdirHm, not sure.
I just put a !drupal_installation_attempted() check in settings.platformsh.php, that works well for us. Not the same, but with #2488350: Switch to a memory cache backend during installation, core will actually not use redis even if you tell it to.
Comment #4
Crell commentedThat's an option I suppose, but would that cause the cache tables to be created and populated in the DB? Ideally we'd avoid that.
Also, it's a bit curious that causing the redis integration to NOT be used during the installer (and thus use the DB cache)... resolves a cache consistency/staleness issue. I'm honestly confused by that.
Comment #5
berdirNot combined with the core issue to use the memory backend, just verifed that locally as I started to use that core patch for an install profile we're working on. The only cache table I get then are cachetags.
Comment #6
memtkmcc commentedThis happens also with Drupal 7, especially when trying to install Commerce Kickstart. Some contrib module is probably causing this.
We couldn't figure out what happens exactly, so we simply turn-off Redis config on the fly on initial site installation in Aegir.
But with Drupal 8 it is complicated even more, because the Redis integration module will do nothing until it is installed (enabled), but you can't install it before the site is installed -- and this may cause unexpected issues, if the site config prepared/created during installation already expects the Redis backend to be available, and you don't have a fallback to standard cache backend (SQL) in place.
With Drupal 7/6 there is no requirement to enable this module, of course, so the WSOD on site install with some D7 distributions is probably a different issue.
Not sure if there is a workaround or if the only solution is just to turn-off Redis integration/configuration during initial site installation.
Comment #7
memtkmcc commentedIt is not a good idea to not get SQL cache tables created at all. You may still need them if there will be any intermittent issue with Redis availability, and normally you should use Redis backend only if Redis server responds and otherwise fallback to SQL cache.
Comment #8
berdirDrupal 8 creates cache tables on the fly, when they are needed, deleting or at least truncating them on production is strongly recommended, otherwise you might copy them or suddenly work against very old cache data, which can actualy mess up a site.
Also, when using the documented platform.sh documentation which explicitly adds the services.yml files and configured the classloader, the redis module does not need to be installed although I'd recommend doing that. See https://docs.platform.sh/frameworks/drupal8/redis.html. That also works elsewhere, you just need to change the dynamic parts.
Comment #9
Crell commentedBerdir: Hm. I tried modifying the code block as you suggest, with !drupal_installation_attempted(), and I still get the same failure condition.
Comment #10
memtkmcc commented@Berdir Interesting, if we can avoid installing Redis module, it will save us a lot of unnecessary dance with switching config on the fly to avoid this chicken/egg situation. Thanks for the hint!
Comment #11
memtkmcc commented@Berdir Yes, SQL cache tables need to be managed regularly and truncated before running backups/clone/migrate etc and before re-using them again. We automate this in BOA/Aegir, so the fallback from Redis, if needed, just works, but it can't be recommended as a general solution, I agree.
Comment #12
badjava commentedI think this issue was created before installing Drupal with sync configuration was added to core. If I try to install Drupal with Redis enabled and properly configured, I get an error like:
I comment out the Redis configuration in settings to get it to install and after the site-install is complete, add the Redis configuration back and it works.
I was able to solve this with:
Perhaps we can update the documentation?
Also a separate issue probably but it would be nice to document how to remove Redis as a module dependency altogether using
$class_loader->addPsr4('Drupal\\redis\\', 'modules/contrib/redis/src');.Comment #13
Crell commentedI don't know what's different, but the
!drupal_installation_attempted()trick is still not working for me with Drupal 8.7.7. I still get the same "encountered an error" after installation completes.What's different here?
Comment #14
Crell commentedComment #15
berdirWhat error exactly? You'll either need to make sure the module is installed or set up the necessary service definition and possibly autoloader configuration yourself.
Comment #16
Crell commentedThe same error as in the OP.
The settings.php file contains (via an include):
Is it an older config style, perhaps?
I have also intermittently started getting this error post-install. I've not narrowed down how/why yet:
Fatal error: Redis::multi(): Can't activate pipeline in multi mode! in /app/web/modules/contrib/redis/src/Cache/PhpRedis.php on line 96
Comment #17
rodrigoaguileraCan the latest fatal error be related with #3068810: Not compatible with php-redis 5 ?
Comment #18
berdirYes, because platform.sh upgraded to php-redis 5 on php 7.3
Comment #19
Crell commentedUgh. Yeah, I'll bet that's it. I'll drop this site back to 7.2 for now. Still not sure about the installer issue.
(What is the fix for the php-redis 5 update?)
Comment #20
bob.hinrichs commentedSame problem Drupal 8.9.1, #12 states a good theory, and that code fixes the Drupal install for me. FYI we are installing form config, and using config_split.
I also share the concern that configuration install cannot run with Redis, which means there is stuff going on with mysql tables during install that will be cruft once the problem stage is over, no?
Comment #21
mxr576Found another possible scenario when using Redis as a cache backend does not work and you can get an error like #12 when you use Redis with an approach like #16 (with uninstalled Redis module).
Comment #22
tondeuse commentedThe following solution works for me on Drupal 10.4. Thanks for all for the ideas and tips, this is team works, as usual.
In this format, I may use redis only for local usage, and the performance benefits it provides. The files, variables and module may be absent on hosted site instance without failure.
My dependency to drupal/redis is declared as a DEV dependency in my composer file, in this case.
In my Dockerfile, for all cases
In my Dockerfile, when running in local dev mode :
An enterprise service inject these files into our hosted containers, this is a solution for local dev that also works for hosted site instances.
In my docker-compose file :
In my local .env file :
In web/sites/default/settings.php
In web/sites/default/settings.redis.php