{"record":{"id":"a6de6cbc034ef33c","repo":"symfony/symfony","slug":"redis-connection-failed-message","errorCode":null,"errorMessage":"Redis connection failed: {message}","messagePattern":"Redis connection failed: (.+?)","errorType":"exception","errorClass":"Symfony\\Component\\Cache\\Exception\\InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Symfony/Component/Cache/Traits/RedisTrait.php","lineNumber":345,"sourceCode":"                        $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']) {\n                $redis = $isRedisExt ? RedisProxy::createLazyProxy($initializer) : RelayProxy::createLazyProxy($initializer);\n            } else {\n                $redis = $initializer();\n            }\n        } elseif (is_a($class, \\RedisArray::class, true)) {\n            foreach ($hosts as $i => $host) {\n                $hosts[$i] = match ($host['scheme']) {\n                    'tcp' => $host['host'].':'.$host['port'],\n                    'tls' => 'tls://'.$host['host'].':'.$host['port'],\n                    default => $host['path'],\n                };\n            }","sourceCodeStart":327,"sourceCodeEnd":363,"githubUrl":"https://github.com/symfony/symfony/blob/698e28026c22cf35d032cdb6e800db48b1535790/src/Symfony/Component/Cache/Traits/RedisTrait.php#L327-L363","documentation":"Thrown when the phpredis \\Redis (or Relay) client raises a \\RedisException / \\Relay::Exception during the actual connect/open attempt in Symfony's Redis adapter initializer (RedisTrait.php:344-346). Symfony wraps the raw driver exception so the underlying message (connection refused, auth failed, DNS error, timeout) is preserved while normalizing it as an InvalidArgumentException. For non-lazy DSNs it fires at createConnection() time; for lazy DSNs it is deferred to the first cache operation.","triggerScenarios":"Calling RedisAdapter::createConnection('redis://host:6379') or building a Redis-backed cache/session/lock pool when $redis->{connect|pconnect}(...) throws. Concretely: server unreachable, AUTH/requirepass mismatch, invalid ACL user, wrong dbindex select, TLS handshake failure, or read_timeout exceeded during open.","commonSituations":"Redis not running in local dev; wrong host/port in cache DSN; password set on server but missing/wrong in DSN; firewall/security group blocking 6379; connecting with 'rediss://' (TLS) to a non-TLS port; Redis 6 ACLs requiring a username but DSN uses 'redis://:pass@host'.","solutions":["Verify reachability: run 'redis-cli -h <host> -p <port> -a <pass> ping' (or with --user for ACL) and confirm you get PONG.","Correct the DSN scheme/auth: 'redis://user:password@host:port/db' (ACL) or 'redis://:password@host' (legacy requirepass); use 'rediss://' only for TLS endpoints.","Ensure the Redis service is up and the port is open between the app host and Redis (security groups, Docker network, k8s Service).","For lazy pools, set 'lazy: false' during a deployment smoke test to surface connect errors at boot instead of on first request.","Raise timeout/read_timeout in the DSN query string only after confirming connectivity (e.g. '?timeout=2&read_timeout=2')."],"exampleFix":"// before\n$dsn = 'redis://localhost:6379'; // fails: server on another host / needs auth\n$pool = RedisAdapter::createConnection($dsn);\n\n// after\n$dsn = 'redis://appuser:s3cret@redis.internal:6379/0';\n// validate first\n$pool = RedisAdapter::createConnection($dsn, ['lazy' => false]);","handlingStrategy":"validation","validationCode":"// Pre-flight reachability before handing the DSN to the adapter\nfunction redisDsnOk(string $dsn, float $timeout = 1): bool {\n    $u = parse_url($dsn);\n    if (!isset($u['host'], $u['port'])) return false;\n    $errno = 0; $errstr = '';\n    $fp = @fsockopen($u['host'], $u['port'], $errno, $errstr, $timeout);\n    if (!is_resource($fp)) return false;\n    fclose($fp);\n    return true;\n}\nif (!redisDsnOk($dsn)) { /* fall back / alert */ }","typeGuard":null,"tryCatchPattern":"// wrap the connection build; retry transient network errors with backoff\nuse Symfony\\Component\\Cache\\Exception\\InvalidArgumentException;\n$attempt = 0;\ndo {\n    try {\n        $conn = RedisAdapter::createConnection($dsn, ['lazy' => false]);\n        break;\n    } catch (InvalidArgumentException $e) {\n        if (++$attempt >= 3 || !str_contains($e->getMessage(), 'connection')) { throw $e; }\n        usleep(200_000 * $attempt);\n    }\n} while (true);","preventionTips":["Validate the DSN host/port with a socket connect test in a deploy smoke step.","Keep Redis credentials in secrets/env, not hardcoded DSNs, so they match across envs.","Run a 'bin/console cache:pool:prune' or a ping against each cache pool after deploy.","Set 'lazy: false' in non-prod so connect errors surface at boot."],"tags":["redis","cache","connection","network","configuration"],"analyzedSha":"698e28026c22cf35d032cdb6e800db48b1535790","analyzedAt":"2026-08-06T23:40:49.025Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}