symfony/symfony · error · Symfony\Component\Cache\Exception\InvalidArgumentException

Invalid Redis DSN.

Error message

Invalid Redis DSN.

What it means

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.

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 698e28026c)

Solutions

  1. rawurlencode user/password and any special characters in the DSN.
  2. Use a known-good minimal DSN first (redis://host:6379) and add components incrementally.
  3. Validate with parse_url() in your bootstrap before handing the value to createConnection().

Example fix

// before: ':' in password breaks parse_url
$dsn = 'redis://user:p@ss:word@host:6379';

// after
$dsn = 'redis://user:'.rawurlencode('p@ss:word').'@host:6379';
Defensive patterns

Strategy: validation

Validate before calling

if (false === parse_url(preg_replace('#^redis(s)?://#', 'file://', $dsn))) {
    throw new \InvalidArgumentException('Malformed Redis DSN (likely unencoded credentials).');
}

Prevention

When it happens

Trigger: Malformed DSN like 'redis://:?:?'; stray characters, unencoded credentials, or a URL with a corrupt port component.

Common situations: Password containing characters that break parse_url when not rawurlencoded; manually concatenating parts of the DSN; copy-paste introducing invisible characters.

Related errors


AI-assisted analysis of symfony/symfony@698e28026c (2026-08-06). Data as JSON: /api/errors/5dfc3eb7aaf8b350. Report an issue: GitHub.