phalcon/cphalcon · error · Phalcon\Acl\Exceptions\ForbiddenWildcard
The component name cannot be '*'
Error message
The component name cannot be '*'
What it means
The Redis session adapter (Phalcon\Session\Adapter\Redis) optionally serializes session access: with 'lockingEnabled' => true, read() must acquire a per-session Redis lock (SET <prefix><id>-lock <token> NX EX <lockExpiry>) before reading. It retries lockRetries times pausing lockWaitTime microseconds between attempts (defaults: 100 x 50,000us = ~5s budget); if every attempt fails because another request holds the lock, AdapterRuntimeError is thrown with the lock key name.
Source
Thrown at phalcon/Acl/Component.zep:26
* file that was distributed with this source code.
*/
namespace Phalcon\Acl;
use Phalcon\Acl\Exceptions\ForbiddenWildcard;
/**
* This class defines component entity and its description
*/
class Component extends AbstractElement implements ComponentInterface
{
/**
* Phalcon\Acl\Component constructor
*/
public function __construct( string name, string description = null)
{
if unlikely name === "*" {
throw new ForbiddenWildcard("component");
}
let this->name = name,
this->description = description;
}
}
View on GitHub (pinned to b7419de9cd)
Solutions
- Raise the wait budget above the longest concurrent request: increase 'lockRetries' and/or 'lockWaitTime'.
- Reduce session lock hold time: shorten requests, or serialize same-session AJAX from the browser side.
- Set 'lockExpiry' above the longest expected request so the lock survives, and remember a request running past lockExpiry silently loses it (per the class docblock) — tune both together.
- Unblock immediately by deleting the stuck key '<prefix><session-id>-lock' in Redis.
- If strict serialization is not required, disable it: 'lockingEnabled' => false.
Example fix
// before
$session = new \Phalcon\Session\Adapter\Redis(
$factory,
['lockingEnabled' => true] // defaults: 100 retries x 50ms ~= 5s budget
);
// after — budget tuned for slow pages + parallel XHR
$session = new \Phalcon\Session\Adapter\Redis(
$factory,
[
'lockingEnabled' => true,
'lockRetries' => 400, // 400 x 50ms = 20s wait budget
'lockWaitTime' => 50000,
'lockExpiry' => 60, // > longest expected request
]
); Defensive patterns
Strategy: retry
Try / catch
use Phalcon\Session\Adapter\Exceptions\AdapterRuntimeError;
session_start(); // triggers read() -> lock acquisition
try {
$session = new \Phalcon\Session\Adapter\Redis($factory, $sessionOptions);
$manager = new \Phalcon\Session\Manager();
$manager->setAdapter($session)->start();
} catch (AdapterRuntimeError $e) {
if (str_contains($e->getMessage(), 'Could not acquire the session lock')) {
// lock contention: back off briefly and retry once; longer term,
// raise lockRetries/lockWaitTime above the longest concurrent request
usleep(250000);
$manager->start();
} else {
throw $e;
}
} Prevention
- Set lockRetries/lockWaitTime so the wait budget exceeds your slowest same-session request.
- Keep lockExpiry above the longest request, and remember requests running past lockExpiry silently lose the lock (class docblock).
- Serialize same-session XHRs client-side to avoid lock queues on dashboards.
- Know the recovery key name: '<prefix><session-id>-lock' — deleting it in Redis unblocks a stuck session instantly.
When it happens
Trigger: Two concurrent requests sharing a session id where the first holds the lock longer than lockRetries * lockWaitTime (default ~5s): parallel AJAX calls while a slow page renders; a previous request crashed after acquiring but before close()/destroy() released the lock; a lockExpiry (default 30s) longer than the wait budget with a stuck key.
Common situations: Dashboards firing many simultaneous same-session XHRs; long-running reports blocking reads; leaked lock keys after PHP-FPM worker kills; locking enabled in production but not in dev, so it only explodes under real concurrency.
Related errors
- Malformed ACL snapshot structure
- Session guard 'name' and 'rememberName' must differ
- The session save path cannot be empty
- The session save path [{path}] is not writable
- {last PHP error message}
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/035152c6a1bd0fdb.
Report an issue: GitHub.