symfony/symfony · error · Symfony\Component\Cache\Exception\InvalidArgumentException
Namespace contains "%s" but only characters in [-+.A-Za-z0-9
Error message
Namespace contains "%s" but only characters in [-+.A-Za-z0-9] are allowed.
What it means
Thrown by PdoAdapter's constructor (PdoAdapter.php:63) when the $namespace contains any character outside [-+.A-Za-z0-9]. Like DoctrineDbalAdapter, the namespace is interpolated into raw SQL LIKE patterns for clear/fetch, so unsafe characters are rejected to prevent query breakage and injection.
Source
Thrown at src/Symfony/Component/Cache/Adapter/PdoAdapter.php:64
* * db_data_col: The column where to store the cache data [default: item_data]
* * db_lifetime_col: The column where to store the lifetime [default: item_lifetime]
* * db_time_col: The column where to store the timestamp [default: item_time]
* * db_username: The username when lazy-connect [default: '']
* * db_password: The password when lazy-connect [default: '']
* * db_connection_options: An array of driver-specific connection options [default: []]
*
* @throws InvalidArgumentException When first argument is not PDO nor Connection nor string
* @throws InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION
* @throws InvalidArgumentException When namespace contains invalid characters
*/
public function __construct(#[\SensitiveParameter] \PDO|string $connOrDsn, string $namespace = '', int $defaultLifetime = 0, array $options = [], ?MarshallerInterface $marshaller = null)
{
if (\is_string($connOrDsn) && str_contains($connOrDsn, '://')) {
throw new InvalidArgumentException(\sprintf('Usage of Doctrine DBAL URL with "%s" is not supported. Use a PDO DSN or "%s" instead.', __CLASS__, DoctrineDbalAdapter::class));
}
if (isset($namespace[0]) && 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]));
}
if ($connOrDsn instanceof \PDO) {
if (\PDO::ERRMODE_EXCEPTION !== $connOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) {
throw new InvalidArgumentException(\sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __CLASS__));
}
$this->conn = $connOrDsn;
} else {
$this->dsn = $connOrDsn;
}
$this->maxIdLength = self::MAX_KEY_LENGTH;
$this->table = $options['db_table'] ?? $this->table;
$this->idCol = $options['db_id_col'] ?? $this->idCol;
$this->dataCol = $options['db_data_col'] ?? $this->dataCol;
$this->lifetimeCol = $options['db_lifetime_col'] ?? $this->lifetimeCol;
$this->timeCol = $options['db_time_col'] ?? $this->timeCol;View on GitHub (pinned to 698e28026c)
Solutions
- Restrict the namespace to [-+.A-Za-z0-9] characters.
- Sanitize dynamic namespaces: $ns = preg_replace('/[^-+.A-Za-z0-9]/', '', $raw);
- Use dots or pluses for hierarchical separation instead of underscores/slashes.
Example fix
// before new PdoAdapter($dsn, 'order_cache/v2'); // after new PdoAdapter($dsn, 'order.cache.v2');
Defensive patterns
Strategy: validation
Validate before calling
if (preg_match('#[^-+.A-Za-z0-9]#', $namespace, $m)) {
throw new \InvalidArgumentException('Invalid cache namespace char: '.$m[0]);
}
new PdoAdapter($dsn, $namespace); Type guard
function isValidCacheNamespace(string $ns): bool
{
return '' === $ns || 1 === preg_match('#^[-+.A-Za-z0-9]*$#', $ns);
} Prevention
- Sanitize tenant/app-derived namespaces: preg_replace('/[^-+.A-Za-z0-9]/', '', $raw).
- Use dots or hyphens for hierarchy, never slashes or underscores.
- Unit-test namespace inputs against the allowed character class.
When it happens
Trigger: Calling `new PdoAdapter($dsn, 'my cache')` (space), `new PdoAdapter($dsn, 'a_b')` (underscore), or any namespace with slash/colon/etc. The regex '#[^-+.A-Za-z0-9]#' catches the first offender.
Common situations: Using a tenant id or app name with underscores/spaces as the cache namespace. Auto-derived namespaces from user input. Copying a namespace format used by a different adapter that allows underscores.
Related errors
- Namespace contains "%s" but only characters in [-+.A-Za-z0-9
- 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").
AI-assisted analysis of symfony/symfony@698e28026c (2026-08-06).
Data as JSON: /api/errors/837276eb8cbf2c6c.
Report an issue: GitHub.