symfony/http-foundation · error · InvalidArgumentException
URLs without scheme are not supported to configure the…
Error message
URLs without scheme are not supported to configure the PdoSessionHandler.
What it means
When the handler receives a URL instead of a raw PDO DSN, buildDsnFromUrl() parses it with parse_url(). If the URL has no scheme (e.g. 'localhost/db' or a bare DSN passed where a URL was expected), the code cannot map it to a PDO driver and throws an InvalidArgumentException.
Solutions
- Ensure the URL includes a scheme, e.g. pdo-mysql://user:pass@host/dbname or mysql://...
- If you meant to pass a raw PDO DSN (e.g. 'mysql:host=localhost;dbname=app'), that is supported too — just don't mix formats; verify the env var value
- Check the framework session handler config (handler_id / dsn option) so a proper URL is injected
Example fix
// before
$handler = new \PdoSessionHandler('localhost/sessions');
// after
$handler = new \PdoSessionHandler('mysql://user:pass@localhost/sessions'); Defensive patterns
Strategy: validation
Validate before calling
$url = $_ENV['DATABASE_URL'] ?? '';
if ($url !== '' && strpbrk(parse_url($url, PHP_URL_SCHEME) ?: '', 'a') === false || parse_url($url, PHP_URL_SCHEME) === false || parse_url($url, PHP_URL_SCHEME) === null) {
throw new \InvalidArgumentException('DATABASE_URL must include a scheme, e.g. mysql://user:pass@host/db');
} Type guard
function hasScheme(string $url): bool {
return is_string(parse_url($url, PHP_URL_SCHEME)) && parse_url($url, PHP_URL_SCHEME) !== '';
} Try / catch
try {
$handler = new \PdoSessionHandler($dsnOrUrl, $options);
} catch (\InvalidArgumentException $e) {
// log config error: URL/DSN malformed or missing scheme
} Prevention
- Always validate the configured DSN/URL env var includes a scheme at boot
- Don't mix raw PDO DSN and URL formats; pick one convention per environment
- Add a config-time lint that parses session handler connection strings
When it happens
Trigger: Passing a connection string/URL without a scheme (e.g. 'database_host/dbname' or missing 'pdo-' prefix style) as the first constructor argument of PdoSessionHandler, so parse_url() yields no 'scheme' key.
Common situations: Config mistakes where an env var like DATABASE_URL is empty or truncated; confusing a PDO DSN with the URL form; YAML/env interpolation dropping the scheme part.
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- The scheme " " is not supported by the PdoSessionHandler…
- You must provide the "database" and "collection" option for…
- Invalid argument $savePath
- " " requires PDO error mode attribute be set to throw…
- SQLite does not support advisory locks.
AI-assisted analysis of symfony/http-foundation@5aea19cd67 (2026-09-13).
Data as JSON: /api/errors/afddae1a57b205f9.
Report an issue: GitHub.
Appendix: source
Thrown at Session/Storage/Handler/PdoSessionHandler.php:529
$params = parse_url($url);
if (false === $params) {
return $dsnOrUrl; // If the URL is not valid, let's assume it might be a DSN already.
}
$params = array_map('rawurldecode', $params);
// Override the default username and password. Values passed through options will still win over these in the constructor.
if (isset($params['user'])) {
$this->username = $params['user'];
}
if (isset($params['pass'])) {
$this->password = $params['pass'];
}
if (!isset($params['scheme'])) {
throw new \InvalidArgumentException('URLs without scheme are not supported to configure the PdoSessionHandler.');
}
$driverAliasMap = [
'mssql' => 'sqlsrv',
'mysql2' => 'mysql', // Amazon RDS, for some weird reason
'postgres' => 'pgsql',
'postgresql' => 'pgsql',
'sqlite3' => 'sqlite',
];
$driver = $driverAliasMap[$params['scheme']] ?? $params['scheme'];
// Doctrine DBAL supports passing its internal pdo_* driver names directly too (allowing both dashes and underscores). This allows supporting the same here.
if (str_starts_with($driver, 'pdo_') || str_starts_with($driver, 'pdo-')) {
$driver = substr($driver, 4);
}
$dsn = null;View on GitHub (pinned to 5aea19cd67)