{"record":{"id":"5dfc3eb7aaf8b350","repo":"symfony/symfony","slug":"invalid-redis-dsn","errorCode":null,"errorMessage":"Invalid Redis DSN.","messagePattern":"Invalid Redis DSN\\.","errorType":"exception","errorClass":"Symfony\\Component\\Cache\\Exception\\InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Symfony/Component/Cache/Traits/RedisTrait.php","lineNumber":124,"sourceCode":"        $auth = null;\n        $params = preg_replace_callback('#^'.$scheme.':(//)?(?:(?:(?<user>[^:@]*+):)?(?<password>[^@]*+)@)?#', static function ($m) use (&$auth) {\n            if (isset($m['password'])) {\n                if (\\in_array($m['user'], ['', 'default'], true)) {\n                    $auth = rawurldecode($m['password']);\n                } else {\n                    $auth = [rawurldecode($m['user']), rawurldecode($m['password'])];\n                }\n\n                if ('' === $auth) {\n                    $auth = null;\n                }\n            }\n\n            return 'file:'.($m[1] ?? '');\n        }, $dsn);\n\n        if (false === $params = parse_url($params)) {\n            throw new InvalidArgumentException('Invalid Redis DSN.');\n        }\n\n        $query = $hosts = [];\n\n        $tls = 'rediss' === $scheme || 'valkeys' === $scheme;\n        $tcpScheme = $tls ? 'tls' : 'tcp';\n\n        if (isset($params['query'])) {\n            parse_str($params['query'], $query);\n\n            if (isset($query['host'])) {\n                if (!\\is_array($hosts = $query['host'])) {\n                    throw new InvalidArgumentException('Invalid Redis DSN: query parameter \"host\" must be an array.');\n                }\n                foreach ($hosts as $host => $parameters) {\n                    if (\\is_string($parameters)) {\n                        parse_str($parameters, $parameters);\n                    }","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/symfony/symfony/blob/698e28026c22cf35d032cdb6e800db48b1535790/src/Symfony/Component/Cache/Traits/RedisTrait.php#L106-L142","documentation":"After stripping the scheme and userinfo, createConnection() rewrites the DSN to a file:// pseudo-URL and runs parse_url(). If parse_url returns false the DSN is structurally malformed and Symfony throws a generic 'Invalid Redis DSN.' rather than proceeding with garbage.","triggerScenarios":"Malformed DSN like 'redis://:?:?'; stray characters, unencoded credentials, or a URL with a corrupt port component.","commonSituations":"Password containing characters that break parse_url when not rawurlencoded; manually concatenating parts of the DSN; copy-paste introducing invisible characters.","solutions":["rawurlencode user/password and any special characters in the DSN.","Use a known-good minimal DSN first (redis://host:6379) and add components incrementally.","Validate with parse_url() in your bootstrap before handing the value to createConnection()."],"exampleFix":"// before: ':' in password breaks parse_url\n$dsn = 'redis://user:p@ss:word@host:6379';\n\n// after\n$dsn = 'redis://user:'.rawurlencode('p@ss:word').'@host:6379';","handlingStrategy":"validation","validationCode":"if (false === parse_url(preg_replace('#^redis(s)?://#', 'file://', $dsn))) {\n    throw new \\InvalidArgumentException('Malformed Redis DSN (likely unencoded credentials).');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["rawurlencode passwords and users in the DSN.","Build the DSN with a helper rather than string concatenation.","Test the DSN with parse_url() in your test suite."],"tags":["redis","dsn","validation"],"analyzedSha":"698e28026c22cf35d032cdb6e800db48b1535790","analyzedAt":"2026-08-06T23:40:49.025Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}