symfony/http-foundation · error · SuspiciousOperationException
Invalid Host " ".
Error message
Invalid Host "%s".
What it means
Request::getHost() validates the Host header. If the host string fails isHostValid (contains invalid characters such as ':' port remnants, spaces, or control chars) the request throws SuspiciousOperationException('Invalid Host "%s".'), because a malformed Host header is a classic host-header-injection vector. This is the first check, distinct from the trusted-hosts check.
Solutions
- Fix the client/proxy Host header value so it contains only a valid hostname.
- Set framework.trusted_hosts (Request::setTrustedHosts([...])) so legitimate hosts pass and untrusted ones are rejected predictably.
- At the web-server level, reject requests whose Host doesn't match your domain (e.g. nginx server_name enforcement).
- Catch SuspiciousOperationException and return 400 instead of letting it bubble as 500.
Example fix
// before (nginx forwarding anything)
proxy_set_header Host $http_host;
// after (enforce known host)
if ($http_host !~* ^(app\.example\.com(:[0-9]+)?)$) { return 400; }
proxy_set_header Host $http_host; Defensive patterns
Strategy: try-catch
Validate before calling
$host = $request->headers->get('HOST', '');
if ($host !== '' && !preg_match('/^[a-zA-Z0-9.\-]+(\[[0-9a-fA-F:]+\])?$/', $host)) {
return new Response('Bad Request', 400);
} Try / catch
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
try {
$host = $request->getHost();
} catch (SuspiciousOperationException $e) {
return new Response('Invalid Host header', 400);
} Prevention
- Configure Request::setTrustedHosts() / framework.trusted_hosts in every environment.
- Enforce Host validation at the web server / reverse proxy layer.
- Never echo or log the raw Host header unvalidated (injection risk).
- Generate absolute URLs from configured base URL, not client Host.
When it happens
Trigger: A client sends Host: 'evil.com:8080/..' or any header with characters outside the allowed set (letters, digits, dots, dashes, brackets for IPv6); calling Request::create() with a URI whose host part is malformed; tampered proxies forwarding bogus Host values.
Common situations: Security scanners or attackers probing for host header injection / cache poisoning; misconfigured reverse proxies forwarding the raw Host; generating absolute URLs in emails from an attacker-controlled Host.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Untrusted Host " ".
- Invalid HTTP method override.
- Invalid URI: Userinfo is malformed.
- Invalid URI: A URI cannot contain a backslash.
- Invalid URI: A URI cannot contain CR/LF/TAB characters.
AI-assisted analysis of symfony/http-foundation@5aea19cd67 (2026-09-13).
Data as JSON: /api/errors/09425ae09f7b70a0.
Report an issue: GitHub.
Appendix: source
Thrown at Request.php:1216
{
if ($this->isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_X_FORWARDED_HOST)) {
$host = $host[0];
} else {
$host = $this->headers->get('HOST') ?: $this->server->get('SERVER_NAME') ?: $this->server->get('SERVER_ADDR', '');
}
// trim and remove port number from host
// host is lowercase as per RFC 952/2181
$host = strtolower(preg_replace('/:\d+$/', '', trim($host)));
// the host can come from the user (HTTP_HOST and depending on the configuration, SERVER_NAME too can come from the user)
if ($host && !self::isHostValid($host)) {
if (!$this->isHostValid) {
return '';
}
$this->isHostValid = false;
throw new SuspiciousOperationException(\sprintf('Invalid Host "%s".', $host));
}
if (self::$trustedHostsLiterals || self::$trustedHostsRegexps) {
// to avoid host header injection attacks, you should provide a list of trusted host patterns
if (self::$trustedHosts) {
trigger_deprecation('symfony/http-foundation', '8.2', 'Populating the "%s::$trustedHosts" property is deprecated; it has no effect anymore.', self::class);
}
if (isset(self::$trustedHostsLiterals[$host])) {
return $host;
}
foreach (self::$trustedHostsRegexps as $regexp) {
if (preg_match($regexp, $host)) {
return $host;
}
}View on GitHub (pinned to 5aea19cd67)