symfony/symfony · error · InvalidArgumentException
Invalid Redis DSN.
Error message
Invalid Redis DSN.
What it means
Thrown by RedisAdapter::createConnection() when parse_url() fails on the normalised DSN, returning false. Before parsing, the method rewrites the scheme to 'file:' and extracts auth credentials via preg_replace_callback; if the resulting string is not a parseable URL, parse_url returns false and the DSN is deemed invalid. This is a catch-all for malformed DSNs that passed the scheme check but are structurally broken.
Solutions
- Provide a complete, well-formed DSN: 'redis://host:6379' or 'redis:///var/run/redis.sock'.
- Percent-encode any special characters in the username/password portion of the DSN.
- Check the environment variable is fully populated (not truncated).
- Log or dump the DSN (without secrets) during debugging to inspect its actual value.
Example fix
// before
$redis = RedisAdapter::createConnection(getenv('REDIS_URL')); // REDIS_URL='redis://'
// after - set a complete DSN
// REDIS_URL='redis://127.0.0.1:6379'
$redis = RedisAdapter::createConnection(getenv('REDIS_URL')); Defensive patterns
Strategy: validation
Validate before calling
// Validate the DSN parses after scheme normalisation.
$test = preg_replace('#^(redis|rediss|valkey|valkeys)s?:#', 'file:', $dsn);
if (false === parse_url($test)) {
throw new \InvalidArgumentException('Redis DSN is malformed: ' . $dsn);
}
$redis = RedisAdapter::createConnection($dsn); Try / catch
try {
$redis = RedisAdapter::createConnection($dsn);
} catch (\Symfony\Component\Cache\Exception\InvalidArgumentException $e) {
if (str_contains($e->getMessage(), 'Invalid Redis DSN')) {
// inspect the env var; likely truncated or unencoded credentials
throw new \RuntimeException('Redis DSN invalid - check REDIS_URL', 0, $e);
}
} Prevention
- Provide a complete DSN with a host (redis://host:6379).
- Percent-encode special characters in DSN credentials.
- Ensure env vars are not truncated; log the DSN length during debugging.
- Unit-test DSN construction if you build it dynamically.
When it happens
Trigger: A DSN like 'redis://' with nothing else (no host), a DSN with illegal characters that survive the scheme/auth rewrite, or a severely malformed string. Also possible with certain malformed unix socket DSNs or unencoded credentials containing reserved characters.
Common situations: Env var truncated or set to a placeholder like 'redis://'. Unencoded special characters in the password (e.g. '@' or ':' not percent-encoded). Copy-paste error leaving stray characters. DSN built by string concatenation with a missing part.
Related errors
- Invalid Redis DSN: it does not start with "redis[s]:" nor…
- Invalid Redis DSN: parameter "dbindex" must be a number.
- Invalid Redis DSN: query parameter "host" must be an array.
- Invalid Redis DSN: missing host.
- Invalid Redis DSN: path and query "dbindex" parameters…
AI-assisted analysis of symfony/symfony@3b11ffbe25 (2026-08-11).
Data as JSON: /api/errors/5dfc3eb7aaf8b350.
Report an issue: GitHub.
Appendix: source
Thrown at src/Symfony/Component/Cache/Traits/RedisTrait.php:124
$auth = null;
$params = preg_replace_callback('#^'.$scheme.':(//)?(?:(?:(?<user>[^:@]*+):)?(?<password>[^@]*+)@)?#', static function ($m) use (&$auth) {
if (isset($m['password'])) {
if (\in_array($m['user'], ['', 'default'], true)) {
$auth = rawurldecode($m['password']);
} else {
$auth = [rawurldecode($m['user']), rawurldecode($m['password'])];
}
if ('' === $auth) {
$auth = null;
}
}
return 'file:'.($m[1] ?? '');
}, $dsn);
if (false === $params = parse_url($params)) {
throw new InvalidArgumentException('Invalid Redis DSN.');
}
$query = $hosts = [];
$tls = 'rediss' === $scheme || 'valkeys' === $scheme;
$tcpScheme = $tls ? 'tls' : 'tcp';
if (isset($params['query'])) {
parse_str($params['query'], $query);
if (isset($query['host'])) {
if (!\is_array($hosts = $query['host'])) {
throw new InvalidArgumentException('Invalid Redis DSN: query parameter "host" must be an array.');
}
foreach ($hosts as $host => $parameters) {
if (\is_string($parameters)) {
parse_str($parameters, $parameters);
}View on GitHub (pinned to 3b11ffbe25)