{"record":{"id":"756cc3bff6171785","repo":"symfony/symfony","slug":"invalid-redis-dsn-it-does-not-start-with-redis-s","errorCode":null,"errorMessage":"Invalid Redis DSN: it does not start with \"redis[s]:\" nor \"valkey[s]:\".","messagePattern":"Invalid Redis DSN: it does not start with \"redis\\[s\\]:\" nor \"valkey\\[s\\]:\"\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Symfony/Component/Cache/Traits/RedisTrait.php","lineNumber":99,"sourceCode":"     * Example DSN:\n     *   - redis://localhost\n     *   - redis://example.com:1234\n     *   - redis://secret@example.com/13\n     *   - redis:///var/run/redis.sock\n     *   - redis://secret@/var/run/redis.sock/13\n     *\n     * @param array $options See self::$defaultConnectionOptions\n     *\n     * @throws InvalidArgumentException when the DSN is invalid\n     */\n    public static function createConnection(#[\\SensitiveParameter] string $dsn, array $options = []): \\Redis|\\RedisArray|\\RedisCluster|\\Predis\\ClientInterface|Relay|RelayCluster\n    {\n        $scheme = match (true) {\n            str_starts_with($dsn, 'redis:') => 'redis',\n            str_starts_with($dsn, 'rediss:') => 'rediss',\n            str_starts_with($dsn, 'valkey:') => 'valkey',\n            str_starts_with($dsn, 'valkeys:') => 'valkeys',\n            default => throw new InvalidArgumentException('Invalid Redis DSN: it does not start with \"redis[s]:\" nor \"valkey[s]:\".'),\n        };\n\n        if (!\\extension_loaded('redis') && !\\extension_loaded('relay') && !class_exists(\\Predis\\Client::class)) {\n            throw new CacheException('Cannot find the \"redis\" extension nor the \"relay\" extension nor the \"predis/predis\" package.');\n        }\n\n        $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                }","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/symfony/symfony/blob/3b11ffbe2520436b0951974d1993dc2144f91dd3/src/Symfony/Component/Cache/Traits/RedisTrait.php#L81-L117","documentation":"Thrown by RedisAdapter::createConnection() when the DSN string does not begin with one of the supported schemes: redis:, rediss:, valkey:, valkeys:. The method uses a match expression on str_starts_with for each scheme; the default arm throws. This is the first validation in DSN parsing, before any host or auth processing.","triggerScenarios":"Passing a DSN like 'tcp://localhost:6379', 'memcached://...', 'localhost:6379' (no scheme), or a typo like 'reddis://...'. Any string lacking a recognised redis/valkey scheme prefix triggers the error immediately.","commonSituations":"Using a generic connection URL from another library. Copying a DSN from a Memcached orDoctrine cache config. Typo in the scheme. Forgetting the scheme entirely. Env var not set so the DSN is empty or a placeholder.","solutions":["Prefix the DSN correctly: 'redis://localhost:6379', 'rediss://...' for TLS, 'valkey://...' for Valkey.","For unix sockets use 'redis:///var/run/redis.sock'.","Check the DSN comes from the intended environment variable and is not empty.","If migrating from Predis/PhpRedis directly, translate their config into a Symfony redis:// DSN."],"exampleFix":"// before\n$redis = RedisAdapter::createConnection('tcp://127.0.0.1:6379');\n\n// after\n$redis = RedisAdapter::createConnection('redis://127.0.0.1:6379');","handlingStrategy":"validation","validationCode":"if (!preg_match('#^(redis|rediss|valkey|valkeys):#', $dsn)) {\n    throw new \\InvalidArgumentException('Redis DSN must start with redis[s]: or valkey[s]:');\n}\n$redis = RedisAdapter::createConnection($dsn);","typeGuard":"function isValidRedisScheme(string $dsn): bool\n{\n    return (bool) preg_match('#^(redis|rediss|valkey|valkeys):#', $dsn);\n}","tryCatchPattern":"try {\n    $redis = RedisAdapter::createConnection($dsn);\n} catch (\\Symfony\\Component\\Cache\\Exception\\InvalidArgumentException $e) {\n    if (str_contains($e->getMessage(), 'does not start with')) {\n        // DSN scheme is wrong; surface to ops, do not auto-correct blindly\n        throw $e;\n    }\n}","preventionTips":["Always use redis://, rediss://, valkey://, or valkeys:// scheme prefixes.","Validate the DSN env var at deploy time.","Differentiate Symfony cache DSNs from Doctrine/Predis direct configs."],"tags":["cache","redis","dsn","configuration","invalid-argument","symfony"],"backgroundTag":null,"analyzedSha":"3b11ffbe2520436b0951974d1993dc2144f91dd3","analyzedAt":"2026-08-11T22:13:02.001Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}