symfony/http-foundation · error · InvalidArgumentException

The scheme " " is not supported by the PdoSessionHandler…

Error message

The scheme "%s" is not supported by the PdoSessionHandler URL configuration. Pass a PDO DSN directly.

What it means

buildDsnFromUrl() recognizes only a fixed set of URL schemes (mapped to PDO drivers like mysql, pgsql, sqlsrv, sqlite, oci). A syntactically valid URL whose scheme is unknown reaches the default match arm and throws an InvalidArgumentException telling the user to pass a PDO DSN directly.

Solutions

  1. Use a supported scheme: mysql, mysql2, postgres, pgsql, sqlite, mssql, sqlsrv, oci, oracle, or 'pdo-' prefixed variants
  2. Fix typos in the scheme (e.g. mysq:// -> mysql://)
  3. If your database has no supported URL scheme, pass a raw PDO DSN string instead (e.g. 'oci:dbname=//host/db')

Example fix

// before
$handler = new \PdoSessionHandler('mongodb://localhost/sessions');
// after
$handler = new \PdoSessionHandler('mysql://user:pass@localhost/sessions');
Defensive patterns

Strategy: validation

Validate before calling

$scheme = parse_url($url, PHP_URL_SCHEME);
$supported = ['mysql','mysql2','postgres','pgsql','sqlite','mssql','sqlsrv','oci','oracle'];
if (!in_array(preg_replace('/^pdo-/', '', (string) $scheme), $supported, true)) {
    throw new \InvalidArgumentException(sprintf('Unsupported session URL scheme "%s"; pass a PDO DSN instead.', $scheme));
}

Type guard

function hasSupportedScheme(string $url): bool {
    $map = ['mysql','mysql2','postgres','pgsql','sqlite','mssql','sqlsrv','oci','oracle'];
    $s = preg_replace('/^pdo-/', '', (string) parse_url($url, PHP_URL_SCHEME));
    return in_array($s, $map, true);
}

Try / catch

try {
    $handler = new \PdoSessionHandler($url, $options);
} catch (\InvalidArgumentException $e) {
    // unsupported scheme: switch to a supported scheme or a raw PDO DSN
}

Prevention

When it happens

Trigger: Passing a URL with a scheme outside the alias map, e.g. 'mongodb://host/db', 'db2://...', or a typo like 'mysq://host' as the PdoSessionHandler DSN argument.

Common situations: Copy-pasting a URL from a different service (Redis, Mongo) into session storage config; typos in scheme names; using schemes like 'mssql://' which is aliased but 'sybase://' or custom schemes are not.

Related errors


AI-assisted analysis of symfony/http-foundation@5aea19cd67 (2026-09-13). Data as JSON: /api/errors/ca5bd54f87fdc7c5. Report an issue: GitHub.

Appendix: source

Thrown at Session/Storage/Handler/PdoSessionHandler.php:611

                $dsn = 'sqlsrv:server=';

                if (isset($params['host'])) {
                    $dsn .= $params['host'];
                }

                if (isset($params['port']) && '' !== $params['port']) {
                    $dsn .= ','.$params['port'];
                }

                if (isset($params['path'])) {
                    $dbName = substr($params['path'], 1); // Remove the leading slash
                    $dsn .= ';Database='.$dbName;
                }

                return $dsn;

            default:
                throw new \InvalidArgumentException(\sprintf('The scheme "%s" is not supported by the PdoSessionHandler URL configuration. Pass a PDO DSN directly.', $params['scheme']));
        }
    }

    /**
     * Helper method to begin a transaction.
     *
     * Since SQLite does not support row level locks, we have to acquire a reserved lock
     * on the database immediately. Because of https://bugs.php.net/42766 we have to create
     * such a transaction manually which also means we cannot use PDO::commit or
     * PDO::rollback or PDO::inTransaction for SQLite.
     *
     * Also MySQLs default isolation, REPEATABLE READ, causes deadlock for different sessions
     * due to https://percona.com/blog/2013/12/12/one-more-innodb-gap-lock-to-avoid/ .
     * So we change it to READ COMMITTED.
     */
    private function beginTransaction(): void
    {
        if (!$this->inTransaction) {

View on GitHub (pinned to 5aea19cd67)