This issue is automatically created based on existing pull request: #41001: Fix Redis unix socket connections in SymfonyAdapterProvider (silent filesystem fallback)
Description (*)
Configuring the Redis cache backend with a unix socket in env.php ('backend' => 'redis', 'server' => '/path/to/redis.sock', 'port' => '0') silently falls back to the filesystem cache adapter — cache and FPC quietly stop using Redis with no error and no log entry.
Root cause: SymfonyAdapterProvider::createPhpRedisConnection() builds the DSN as redis://host:port/db unconditionally:
$baseDsn = $password
? sprintf('redis://%s@%s:%d/%d', urlencode($password), $host, $port, $database)
: sprintf('redis://%s:%d/%d', $host, $port, $database);
With a socket config this yields redis:///path/to/redis.sock:0/1. Symfony's RedisTrait::createConnection() strips the trailing /1 as the dbindex and resolves the unix socket file as /path/to/redis.sock:0, which does not exist. The connection failure is swallowed by createAdapter()'s catch-all \Exception handler, which falls back to createFilesystemAdapter() without logging. The Predis fallback path (createOptimizedPredisConnection()) has the same gap — it always builds scheme => tcp parameters.
Fix: treat a host beginning with / as a unix socket path — the same convention used by phpredis's connect() and by Credis behind the previous Magento\Framework\Cache\Backend\Redis, so socket configurations that worked before the Symfony cache migration work again unchanged — and emit Symfony's documented socket DSN form redis://[auth@]/path/to/redis.sock/<dbindex>. The Predis parameter builder likewise emits scheme => unix, path => ... for socket hosts. A hostname can never begin with / (DNS labels are letters/digits/hyphens), so the check cannot misroute TCP configurations.
Minor related correction: the password is now rawurlencode()d rather than urlencode()d, matching the rawurldecode() Symfony applies when parsing DSN userinfo (differs only for passwords containing spaces).
DSN construction and Predis connection parameters are extracted into small private builder methods (buildRedisBaseDsn(), buildPredisConnectionParameters()) so they are unit-testable; behavior is otherwise unchanged.
Related Pull Requests
Same fix submitted to Mage-OS: mage-os/mageos-magento2#294
Fixed Issues (if relevant)
N/A (root cause analysis included above)
Manual testing scenarios (*)
- Configure Redis over a unix socket in
app/etc/env.php for default and page_cache:
'backend' => 'redis',
'backend_options' => [
'server' => '/var/run/redis/redis.sock',
'port' => '0',
'database' => '1',
],
- Flush cache, browse the storefront.
- Before the fix:
redis-cli -s /var/run/redis/redis.sock -n 1 dbsize stays at 0 and var/cache/ fills with filesystem cache entries.
- After the fix: Redis dbsize grows,
var/cache/ is no longer populated by the cache frontend.
- Regression check: TCP configurations (
'server' => '127.0.0.1', 'port' => '6379'), with and without password, behave as before.
New unit test Magento\Framework\Cache\Test\Unit\Frontend\Adapter\SymfonyAdapterProviderTest covers TCP and socket DSN/parameter building, with/without auth, password encoding of reserved characters, and port being ignored for sockets (11 tests, 11 assertions, PHPUnit 12).
Questions or comments
The catch-all fallback in createAdapter() that swallows connection errors without logging turns any Redis misconfiguration into an invisible performance regression; a follow-up adding at least a log line may be worthwhile.
Contribution checklist (*)
Also submitted to Mage-OS 3: mage-os/mageos-magento2#294
This issue is automatically created based on existing pull request: #41001: Fix Redis unix socket connections in SymfonyAdapterProvider (silent filesystem fallback)
Description (*)
Configuring the Redis cache backend with a unix socket in
env.php('backend' => 'redis','server' => '/path/to/redis.sock','port' => '0') silently falls back to the filesystem cache adapter — cache and FPC quietly stop using Redis with no error and no log entry.Root cause:
SymfonyAdapterProvider::createPhpRedisConnection()builds the DSN asredis://host:port/dbunconditionally:With a socket config this yields
redis:///path/to/redis.sock:0/1. Symfony'sRedisTrait::createConnection()strips the trailing/1as the dbindex and resolves the unix socket file as/path/to/redis.sock:0, which does not exist. The connection failure is swallowed bycreateAdapter()'s catch-all\Exceptionhandler, which falls back tocreateFilesystemAdapter()without logging. The Predis fallback path (createOptimizedPredisConnection()) has the same gap — it always buildsscheme => tcpparameters.Fix: treat a host beginning with
/as a unix socket path — the same convention used by phpredis'sconnect()and by Credis behind the previousMagento\Framework\Cache\Backend\Redis, so socket configurations that worked before the Symfony cache migration work again unchanged — and emit Symfony's documented socket DSN formredis://[auth@]/path/to/redis.sock/<dbindex>. The Predis parameter builder likewise emitsscheme => unix, path => ...for socket hosts. A hostname can never begin with/(DNS labels are letters/digits/hyphens), so the check cannot misroute TCP configurations.Minor related correction: the password is now
rawurlencode()d rather thanurlencode()d, matching therawurldecode()Symfony applies when parsing DSN userinfo (differs only for passwords containing spaces).DSN construction and Predis connection parameters are extracted into small private builder methods (
buildRedisBaseDsn(),buildPredisConnectionParameters()) so they are unit-testable; behavior is otherwise unchanged.Related Pull Requests
Same fix submitted to Mage-OS: mage-os/mageos-magento2#294
Fixed Issues (if relevant)
N/A (root cause analysis included above)
Manual testing scenarios (*)
app/etc/env.phpfordefaultandpage_cache:redis-cli -s /var/run/redis/redis.sock -n 1 dbsizestays at 0 andvar/cache/fills with filesystem cache entries.var/cache/is no longer populated by the cache frontend.'server' => '127.0.0.1', 'port' => '6379'), with and without password, behave as before.New unit test
Magento\Framework\Cache\Test\Unit\Frontend\Adapter\SymfonyAdapterProviderTestcovers TCP and socket DSN/parameter building, with/without auth, password encoding of reserved characters, and port being ignored for sockets (11 tests, 11 assertions, PHPUnit 12).Questions or comments
The catch-all fallback in
createAdapter()that swallows connection errors without logging turns any Redis misconfiguration into an invisible performance regression; a follow-up adding at least a log line may be worthwhile.Contribution checklist (*)
Also submitted to Mage-OS 3: mage-os/mageos-magento2#294