symfony/http-foundation · error · BadRequestException
Invalid URI: Scheme is malformed.
Error message
Invalid URI: Scheme is malformed.
What it means
Request::create() validates the scheme portion of the supplied URI before parsing. If the text before the first ':' looks like a scheme (a colon is present before any '/', '?', or '#') but contains characters outside the legal scheme alphabet (letters, digits, '+', '-', '.') — or contains no letters at all — it throws BadRequestException('Invalid URI: Scheme is malformed.').
Solutions
- Fix the URI string: ensure a valid scheme (letter first, then letters/digits/+/-/.) followed by '://'
- Trim and sanitize user-supplied URLs before passing to Request::create
- If the input may be relative, only pass URIs without a bogus prefix, or prepend the intended scheme/host explicitly
- Catch BadRequestException and return a 400 response for invalid user input
Example fix
// before
$request = Request::create('ht tp://example.com/path'); // throws
// after
$request = Request::create('https://example.com/path'); Defensive patterns
Strategy: validation
Validate before calling
if (preg_match('#^[A-Za-z][A-Za-z0-9+.\-]*:#', $uri) && !preg_match('#^[A-Za-z][A-Za-z0-9+.\-]*://#', $uri)) {
throw new \InvalidArgumentException('Scheme is malformed');
} Type guard
function hasValidScheme(string $uri): bool {
$i = strcspn($uri, ':/?#');
return !($i && ':' === ($uri[$i] ?? null) && (strspn($uri, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-.') !== $i || strcspn($uri, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')));
} Try / catch
try {
$request = Request::create($uri);
} catch (BadRequestException $e) {
return new Response('Invalid URL', 400);
} Prevention
- Trim whitespace and normalize user-supplied URLs before Request::create
- Ensure schemes look like 'scheme://', letters first
- urlencode arbitrary path segments before composing URIs
- Validate with filter_var($uri, FILTER_VALIDATE_URL) upstream
When it happens
Trigger: Request::create('ht tp://example.com'), '1http://example.com', '::example.com', or any URI whose prefix before ':' contains spaces, underscores, or starts with a non-letter while still having a ':' before the first /?#.
Common situations: Copied URLs with stray spaces or full-width characters; programmatically built URIs with unencoded characters; mistyped scheme like 'http_://'; user-supplied redirect targets passed to Request::create in tests or controllers.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid URI.
- Invalid URI: Userinfo is malformed.
- Invalid URI: Host is malformed.
- Invalid URI: A URI cannot contain a backslash.
- Invalid URI: A URI must not start nor end with ASCII…
AI-assisted analysis of symfony/http-foundation@5aea19cd67 (2026-09-13).
Data as JSON: /api/errors/71525de687d23838.
Report an issue: GitHub.
Appendix: source
Thrown at Request.php:394
'SERVER_PORT' => 80,
'HTTP_HOST' => 'localhost',
'HTTP_USER_AGENT' => 'Symfony',
'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'HTTP_ACCEPT_LANGUAGE' => 'en-us,en;q=0.5',
'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
'REMOTE_ADDR' => '127.0.0.1',
'SCRIPT_NAME' => '',
'SCRIPT_FILENAME' => '',
'SERVER_PROTOCOL' => 'HTTP/1.1',
'REQUEST_TIME' => time(),
'REQUEST_TIME_FLOAT' => microtime(true),
], $server);
$server['PATH_INFO'] = '';
$server['REQUEST_METHOD'] = strtoupper($method);
if (($i = strcspn($uri, ':/?#')) && ':' === ($uri[$i] ?? null) && (strspn($uri, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-.') !== $i || strcspn($uri, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'))) {
throw new BadRequestException('Invalid URI: Scheme is malformed.');
}
if (false === $components = parse_url(\strlen($uri) !== strcspn($uri, '?#') ? $uri : $uri.'#')) {
throw new BadRequestException('Invalid URI.');
}
$part = ($components['user'] ?? '').':'.($components['pass'] ?? '');
if (':' !== $part && \strlen($part) !== strcspn($part, '[]')) {
throw new BadRequestException('Invalid URI: Userinfo is malformed.');
}
if (($part = $components['host'] ?? '') && !self::isHostValid($part)) {
throw new BadRequestException('Invalid URI: Host is malformed.');
}
if (false !== ($i = strpos($uri, '\\')) && $i < strcspn($uri, '?#')) {
throw new BadRequestException('Invalid URI: A URI cannot contain a backslash.');
}
if (\strlen($uri) !== strcspn($uri, "\r\n\t")) {
throw new BadRequestException('Invalid URI: A URI cannot contain CR/LF/TAB characters.');View on GitHub (pinned to 5aea19cd67)