symfony/routing · error · RuntimeException
The container parameter
Error message
The container parameter "%s" resolves to an env var, which is not allowed in routing configuration.
What it means
After fetching a container parameter for a route value, the Router checks whether the resolved value itself is (or resolves through) an env var, detected by the internal env_... processor marker pattern. This error means a parameter used in routing indirectly resolves to an env var, which is forbidden because routing is compiled without runtime env access.
Solutions
- Remove the env indirection: give the parameter a static value in routing context.
- Bind the env var to a concrete default via %env(default:...)%% only where runtime resolution is allowed — but not for routing values.
- Pass the value as a route default at runtime instead of relying on container compilation.
Example fix
// before (parameters.yaml) app_host: '%env(APP_HOST)%' // after app_host: 'example.com' # or resolve env outside routing
Defensive patterns
Strategy: validation
Validate before calling
$v = $container->getParameter($name);
if (is_string($v) && preg_match('/env_[a-f0-9]{16}_\w+_[a-f0-9]{32}/Ui', $v)) {
throw new LogicException("Parameter $name resolves to an env var; not usable in routing.");
} Type guard
function isRoutingSafeParam(mixed $v): bool { return !is_string($v) || !preg_match('/env_[a-f0-9]{16}_\w+_[a-f0-9]{32}/Ui', $v); } Try / catch
try { $url = $generator->generate($name); } catch (RuntimeException $e) { // param resolves to env var
$logger->error($e->getMessage());
} Prevention
- Avoid parameter chains that end in %env()% for values used by routing
- Give such parameters static values or defaults
- Inspect resolved parameters with debug:container --parameter
When it happens
Trigger: A route references %param% where the parameter's value contains or equals a processed env placeholder (matching /env_[a-f0-9]{16}_\w+_[a-f0-9]{32}/).
Common situations: Chained parameters where parameters.yaml defines foo: '%env(BAR)%' and a route uses %foo%; indirection through imported config files.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- Using "%% %%" is not allowed in routing configuration.
- The container parameter
- Unable to generate a URL for the named route
- Target route " " for alias " " does not exist.
- Unable to generate a URL for the named route
AI-assisted analysis of symfony/routing@83fa223250 (2026-09-14).
Data as JSON: /api/errors/2c03a47b6b1dbb27.
Report an issue: GitHub.
Appendix: source
Thrown at DependencyInjection/Router.php:181
if (!\is_string($value)) {
return $value;
}
$escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($value) {
// skip %%
if (!isset($match[1])) {
return '%%';
}
if (preg_match('/^env\((?:\w++:)*+\w++\)$/', $match[1])) {
throw new RuntimeException(\sprintf('Using "%%%s%%" is not allowed in routing configuration.', $match[1]));
}
$resolved = ($this->paramFetcher)($match[1]);
if (\is_string($resolved) && preg_match('/env_[a-f0-9]{16}_\w+_[a-f0-9]{32}/Ui', $resolved)) {
throw new RuntimeException(\sprintf('The container parameter "%s" resolves to an env var, which is not allowed in routing configuration.', $match[1]));
}
if (\is_scalar($resolved)) {
$this->collectedParameters[$match[1]] = $resolved;
if (\is_string($resolved)) {
$resolved = $this->resolve($resolved);
}
if (\is_scalar($resolved)) {
return false === $resolved ? '0' : (string) $resolved;
}
}
throw new RuntimeException(\sprintf('The container parameter "%s", used in the route configuration value "%s", must be a string or numeric, but it is of type "%s".', $match[1], $value, get_debug_type($resolved)));
}, $value);
return str_replace('%%', '%', $escapedValue);View on GitHub (pinned to 83fa223250)