{"record":{"id":"f94f40a792f8e19a","repo":"symfony/symfony","slug":"redis-connection-failed-error","errorCode":null,"errorMessage":"Redis connection failed: {error}.","messagePattern":"Redis connection failed: (.+?)\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"critical","filePath":"src/Symfony/Component/Cache/Traits/RedisTrait.php","lineNumber":333,"sourceCode":"                try {\n                    $extra = [\n                        'stream' => self::filterSslOptions($params['ssl'] ?? []) ?: null,\n                    ];\n\n                    if (null !== $params['auth']) {\n                        $extra['auth'] = $params['auth'];\n                    }\n                    @$redis->{$connect}($host, $port, (float) $params['timeout'], (string) $params['persistent_id'], $params['retry_interval'], $params['read_timeout'], ...\\defined('Redis::SCAN_PREFIX') || !$isRedisExt ? [$extra] : []);\n\n                    set_error_handler(static function ($type, $msg) use (&$error) { $error = $msg; });\n                    try {\n                        $isConnected = $redis->isConnected();\n                    } finally {\n                        restore_error_handler();\n                    }\n                    if (!$isConnected) {\n                        $error = preg_match('/^Redis::p?connect\\(\\): (.*)/', $error ?? $redis->getLastError() ?? '', $error) ? \\sprintf(' (%s)', $error[1]) : '';\n                        throw new InvalidArgumentException('Redis connection failed: '.$error.'.');\n                    }\n\n                    if (0 < $params['tcp_keepalive'] && (!$isRedisExt || \\defined('Redis::OPT_TCP_KEEPALIVE'))) {\n                        $redis->setOption($isRedisExt ? \\Redis::OPT_TCP_KEEPALIVE : Relay::OPT_TCP_KEEPALIVE, $params['tcp_keepalive']);\n                    }\n\n                    if (!$redis->select($params['dbindex'])) {\n                        $e = preg_replace('/^ERR /', '', $redis->getLastError());\n                        throw new InvalidArgumentException('Redis connection failed: '.$e.'.');\n                    }\n                } catch (\\RedisException|\\Relay\\Exception $e) {\n                    throw new InvalidArgumentException('Redis connection failed: '.$e->getMessage());\n                }\n\n                return $redis;\n            };\n\n            if ($params['lazy']) {","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/symfony/symfony/blob/3b11ffbe2520436b0951974d1993dc2144f91dd3/src/Symfony/Component/Cache/Traits/RedisTrait.php#L315-L351","documentation":"An InvalidArgumentException from the Redis cache adapter thrown when the underlying ext-redis or Relay connect()/pconnect() call did not establish a connection (isConnected() returned false), or when a subsequent $redis->select($dbindex) failed, or when the connection attempt raised a \\RedisException / \\Relay\\Exception. The message embeds the specific low-level error extracted via the error handler or getLastError(). This is a runtime connectivity / authentication failure.","triggerScenarios":"Redis server down or refusing connections; wrong port; AUTH failure (wrong password); SELECT failure (dbindex out of range e.g. SELECT 9999 on a Redis with 16 DBs); TLS/cert handshake failure for 'rediss://' DSNs; connection timeout because the host is unreachable; firewall dropping packets.","commonSituations":"Redis container not started in docker-compose; REDIS_URL points to a host that only resolves inside another network namespace; password rotated but DSN not updated; switching from redis:// to rediss:// without configuring SSL context; Redis configured with requirepass but DSN has no credentials.","solutions":["Read the embedded {error} text — it names the actual cause (Connection refused, NOAUTH, SELECT failed, etc.).","Test connectivity directly: 'redis-cli -h <host> -p <port> -a <password> PING'.","If NOAUTH: add credentials to the DSN: 'redis://:password@host:6379' or 'redis://user:password@host:6379' for ACL.","If SELECT failed: lower the dbindex to a valid database number (default Redis ships 16 DBs, 0-15).","For TLS errors on rediss://: provide ssl context options in the query string, e.g. '?ssl[verify_peer]=0' for self-signed or proper CA bundle paths.","Increase timeout via '?timeout=5' if the cause is a slow network."],"exampleFix":"// before\nREDIS_URL=redis://redis-prod:6379\n// error: Redis connection failed: (NOAUTH Authentication required.).\n\n// after\nREDIS_URL=redis://:${REDIS_PASSWORD}@redis-prod:6379","handlingStrategy":"try-catch","validationCode":"// Pre-flight connectivity test matching the DSN\nfunction pingRedis(string $dsn, float $timeout = 2): void\n{\n    $host = parse_url($dsn, PHP_URL_HOST);\n    $port = parse_url($dsn, PHP_URL_PORT) ?: 6379;\n    $scheme = parse_url($dsn, PHP_URL_SCHEME) ?? 'redis';\n    if ('rediss' === $scheme || 'valkeys' === $scheme) {\n        // TLS: skip raw fsockopen; use stream_socket_client with SSL\n        $remote = \"tls://{$host}:{$port}\";\n    } else {\n        $remote = \"tcp://{$host}:{$port}\";\n    }\n    $fp = @stream_socket_client($remote, $errNo, $errStr, $timeout);\n    if (!$fp) {\n        throw new \\RuntimeException(\"Cannot reach Redis at {$host}:{$port}: {$errStr}\");\n    }\n    fclose($fp);\n}","typeGuard":null,"tryCatchPattern":"use Symfony\\Component\\Cache\\Exception\\InvalidArgumentException as CacheIA;\ntry {\n    $conn = RedisAdapter::createConnection($dsn);\n} catch (CacheIA $e) {\n    if (str_starts_with($e->getMessage(), 'Redis connection failed')) {\n        // classify: NOAUTH -> prompt credentials, SELECT -> lower dbindex, refused -> ops alert\n        $msg = $e->getMessage();\n        match (true) {\n            str_contains($msg, 'NOAUTH') => /* rotate creds */ null,\n            str_contains($msg, 'SELECT') => /* check dbindex range */ null,\n            default => /* network/ops */ null,\n        };\n    }\n    throw $e;\n}","preventionTips":["Store credentials in secrets (e.g. symfony/secret-vault), not plain env vars.","Always run 'redis-cli ... PING' as part of deploy verification.","Use TLS for cross-network Redis and pre-validate SSL context."],"tags":["redis","cache","network","authentication","runtime","symfony"],"backgroundTag":null,"analyzedSha":"3b11ffbe2520436b0951974d1993dc2144f91dd3","analyzedAt":"2026-08-11T22:13:02.001Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}