symfony/symfony · error · InvalidArgumentException
Invalid Redis DSN: it does not start with "redis[s]:" nor…
Error message
Invalid Redis DSN: it does not start with "redis[s]:" nor "valkey[s]:".
What it means
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.
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.
Example fix
// before
$redis = RedisAdapter::createConnection('tcp://127.0.0.1:6379');
// after
$redis = RedisAdapter::createConnection('redis://127.0.0.1:6379'); Defensive patterns
Strategy: validation
Validate before calling
if (!preg_match('#^(redis|rediss|valkey|valkeys):#', $dsn)) {
throw new \InvalidArgumentException('Redis DSN must start with redis[s]: or valkey[s]:');
}
$redis = RedisAdapter::createConnection($dsn); Type guard
function isValidRedisScheme(string $dsn): bool
{
return (bool) preg_match('#^(redis|rediss|valkey|valkeys):#', $dsn);
} Try / catch
try {
$redis = RedisAdapter::createConnection($dsn);
} catch (\Symfony\Component\Cache\Exception\InvalidArgumentException $e) {
if (str_contains($e->getMessage(), 'does not start with')) {
// DSN scheme is wrong; surface to ops, do not auto-correct blindly
throw $e;
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Invalid Redis DSN.
- 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/756cc3bff6171785.
Report an issue: GitHub.
Appendix: 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 3b11ffbe25)