symfony/routing · error · InvalidArgumentException

Route host " " cannot contain " " as a host parameter.

Error message

Route host "%s" cannot contain "%s" as a host parameter.

What it means

Symfony's RouteCompiler rejects a route whose host section uses the reserved parameter name "_firewall" as a host variable. The "_firewall" key selects which firewall handles the route internally; if it were allowed as a host parameter, an attacker could pick the firewall simply by sending a chosen Host header. The compiler therefore throws an InvalidArgumentException during compile() to prevent this security hole.

Solutions

  1. Rename the host variable in the route host to something other than "_firewall", e.g. {subdomain}.example.com.
  2. If you intended to select a firewall, use the proper mechanism instead (firewall context / matcher configuration), not a route host parameter.
  3. Audit route definitions (YAML/PHP/attributes) for {_firewall} in the host key or setHost() calls.

Example fix

// before
$route->setHost('{_firewall}.example.com');

// after
$route->setHost('{subdomain}.example.com');
Defensive patterns

Strategy: validation

Validate before calling

// before compiling / registering the route
if (str_contains($route->getHost(), '{_firewall}')) {
    throw new \InvalidArgumentException('Route host must not use the reserved {_firewall} parameter.');
}

Try / catch

// optional safety net when compiling dynamic routes
try {
    (new RouteCompiler())->compile($route);
} catch (\InvalidArgumentException $e) {
    $this->logger->error('Invalid route host parameter', ['exception' => $e]);
}

Prevention

When it happens

Trigger: Calling RouteCompiler::compile() (directly or via RouteCollection compilation) on a route whose host, e.g. ->setHost('{_firewall}.example.com') or any host containing {_firewall}, is compiled.

Common situations: Copy-pasting a path parameter name into the host part of a route; misreading reserved names and thinking _firewall is a normal route argument; generating route hosts dynamically from user/controller parameter names.

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


AI-assisted analysis of symfony/routing@83fa223250 (2026-09-14). Data as JSON: /api/errors/7c0a44cd4717d63f. Report an issue: GitHub.

Appendix: source

Thrown at RouteCompiler.php:59

     *                                   a PCRE subpattern
     */
    public static function compile(Route $route): CompiledRoute
    {
        $hostVariables = [];
        $variables = [];
        $hostRegex = null;
        $hostTokens = [];

        if ('' !== $host = $route->getHost()) {
            $result = self::compilePattern($route, $host, true);

            $hostVariables = $result['variables'];
            $variables = $hostVariables;

            foreach ($hostVariables as $hostParam) {
                // "_firewall" selects the firewall handling the route; as a host parameter it would let the Host header choose it
                if ('_firewall' === $hostParam) {
                    throw new \InvalidArgumentException(\sprintf('Route host "%s" cannot contain "%s" as a host parameter.', $host, $hostParam));
                }
            }

            $hostTokens = $result['tokens'];
            $hostRegex = $result['regex'];
        }

        $locale = $route->getDefault('_locale');
        if (null !== $locale && null !== $route->getDefault('_canonical_route') && preg_quote($locale) === $route->getRequirement('_locale')) {
            $requirements = $route->getRequirements();
            unset($requirements['_locale']);
            $route->setRequirements($requirements);
            $route->setPath(str_replace('{_locale}', $locale, $route->getPath()));
        }

        $path = $route->getPath();

        $result = self::compilePattern($route, $path, false);

View on GitHub (pinned to 83fa223250)