symfony/symfony · error · Symfony\Component\Cache\Exception\InvalidArgumentException
Invalid Redis DSN: it does not start with "redis[s]:" nor "v
Error message
Invalid Redis DSN: it does not start with "redis[s]:" nor "valkey[s]:".
What it means
createConnection() begins by detecting the DSN scheme with a match expression. Only redis:, rediss:, valkey:, valkeys: are recognised; anything else is rejected immediately as a clearly invalid Redis DSN rather than producing a confusing parse failure later.
Source
Thrown at src/Symfony/Component/Cache/Traits/RedisTrait.php:99
* Example DSN:
* - redis://localhost
* - redis://example.com:1234
* - redis://secret@example.com/13
* - redis:///var/run/redis.sock
* - redis://secret@/var/run/redis.sock/13
*
* @param array $options See self::$defaultConnectionOptions
*
* @throws InvalidArgumentException when the DSN is invalid
*/
public static function createConnection(#[\SensitiveParameter] string $dsn, array $options = []): \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface|Relay|RelayCluster
{
$scheme = match (true) {
str_starts_with($dsn, 'redis:') => 'redis',
str_starts_with($dsn, 'rediss:') => 'rediss',
str_starts_with($dsn, 'valkey:') => 'valkey',
str_starts_with($dsn, 'valkeys:') => 'valkeys',
default => throw new InvalidArgumentException('Invalid Redis DSN: it does not start with "redis[s]:" nor "valkey[s]:".'),
};
if (!\extension_loaded('redis') && !\extension_loaded('relay') && !class_exists(\Predis\Client::class)) {
throw new CacheException('Cannot find the "redis" extension nor the "relay" extension nor the "predis/predis" package.');
}
$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;
}View on GitHub (pinned to 698e28026c)
Solutions
- Prefix the DSN with a supported scheme: redis://, rediss:// (TLS), valkey://, valkeys://.
- Validate the env value at boot: if (!preg_match('#^redis[s]?://|^valkey[s]?://#', $dsn)) fail loud.
- Check for accidental whitespace: trim($dsn).
Example fix
// before
RedisAdapter::createConnection(getenv('REDIS_URL')); // 'localhost:6379'
// after
RedisAdapter::createConnection('redis://'.trim(getenv('REDIS_URL'))); Defensive patterns
Strategy: validation
Validate before calling
$dsn = trim((string) $dsn);
if (!preg_match('#^redis[s]?://|^valkey[s]?://#', $dsn)) {
throw new \InvalidArgumentException('REDIS_URL must start with redis[s]:/valkey[s]:');
} Type guard
function validRedisScheme(string $dsn): bool {
return (bool) preg_match('#^redis[s]?://|^valkey[s]?://#', $dsn);
} Prevention
- Always include a supported scheme in REDIS_URL.
- Trim env vars before use.
- Fail fast at boot with an explicit scheme check.
When it happens
Trigger: Passing 'memcached://localhost'; a typo like 'reddis://' or 'rediss' (no colon); an env var that resolved to an empty string; passing a host without a scheme ('localhost:6379').
Common situations: Wrong REDIS_URL scheme; copy-pasted a Doctrine cache URL expecting memcached; trailing-space or BOM in env var stripping the scheme.
Related errors
- Invalid Redis DSN.
- Invalid Redis DSN: query parameter "host" must be an array.
- Invalid Redis DSN: parameter "dbindex" must be a number.
- Invalid Redis DSN: missing host.
- Invalid Redis DSN: path and query "dbindex" parameters misma
AI-assisted analysis of symfony/symfony@698e28026c (2026-08-06).
Data as JSON: /api/errors/756cc3bff6171785.
Report an issue: GitHub.