symfony/symfony · error · Symfony\Component\Cache\Exception\InvalidArgumentException
Namespace contains "%s" but only characters in [-+_.A-Za-z0-
Error message
Namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.
What it means
FilesystemCommonTrait::init() builds the cache directory by appending the namespace to the base directory, so the namespace becomes a literal path segment. Characters outside [-+_.A-Za-z0-9] (notably /, \, :, NUL) could cause path traversal or invalid paths, so they are rejected up front.
Source
Thrown at src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php:35
* @author Nicolas Grekas <p@tchwork.com>
*
* @internal
*/
trait FilesystemCommonTrait
{
private string $directory;
private string $tmpSuffix;
private function init(string $namespace, ?string $directory): void
{
if (!isset($directory[0])) {
$directory = sys_get_temp_dir().\DIRECTORY_SEPARATOR.'symfony-cache';
} else {
$directory = realpath($directory) ?: $directory;
}
if (isset($namespace[0])) {
if (preg_match('#[^-+_.A-Za-z0-9]#', $namespace, $match)) {
throw new InvalidArgumentException(\sprintf('Namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
}
$directory .= \DIRECTORY_SEPARATOR.$namespace;
} else {
$directory .= \DIRECTORY_SEPARATOR.'@';
}
if (!is_dir($directory)) {
@mkdir($directory, 0o777, true);
}
$directory .= \DIRECTORY_SEPARATOR;
// On Windows the whole path is limited to 258 chars
if ('\\' === \DIRECTORY_SEPARATOR && \strlen($directory) > 234) {
throw new InvalidArgumentException(\sprintf('Cache directory too long (%s).', $directory));
}
$this->directory = $directory;
}
protected function doClear(string $namespace): boolView on GitHub (pinned to 698e28026c)
Solutions
- Restrict the namespace to [-+_.A-Za-z0-9] (use - or _ as separators).
- Hash or slugify arbitrary input: preg_replace('#[^-+_.A-Za-z0-9]#', '_', $input).
- For per-tenant separation that needs '/', rely on the adapter's own hashed sharding instead of the namespace.
Example fix
// before
new FilesystemAdapter('tenant:42', 0, $dir);
// after
new FilesystemAdapter('tenant_42', 0, $dir); Defensive patterns
Strategy: validation
Validate before calling
$ns = preg_replace('#[^-+_.A-Za-z0-9]#', '_', $rawNamespace);
new FilesystemAdapter($ns, 0, $dir); Type guard
function isValidNamespace(string $ns): bool {
return preg_match('#^[^-+_.A-Za-z0-9]*$#', $ns) || !preg_match('#[^-+_.A-Za-z0-9]#', $ns);
} Prevention
- Restrict namespaces to [-+_.A-Za-z0-9].
- Slugify tenant-derived namespaces before use.
- Reject slashes/colons at the config layer.
When it happens
Trigger: new FilesystemAdapter('app:v2', 0, $dir); new FilesystemAdapter('tenant/42', ...); passing a namespace containing a space or colon.
Common situations: Using a colon because it is conventional for Redis key prefixes; using a slash to namespace per-tenant; copying a namespace from a URL or env var that contains slashes.
Related errors
- Cache namespace "%s" contains empty sub-namespace.
- Namespace must be %d chars max, %d given ("%s").
- Cache namespace "%s" contains empty sub-namespace.
- Namespace must be %d chars max, %d given ("%s").
- Namespace contains "%s" but only characters in [-+.A-Za-z0-9
AI-assisted analysis of symfony/symfony@698e28026c (2026-08-06).
Data as JSON: /api/errors/387911e7c81d0a15.
Report an issue: GitHub.