phalcon/cphalcon · error · Phalcon\Auth\Exceptions\DefaultGuardNotRegistered
No default guard registered
Error message
No default guard registered
What it means
Manager::guard() with no argument returns the default guard. The default is only set when a guard is registered with default: true (ManagerFactory::load() passes the 'default' flag from config to Manager::addGuard(), which stores it as defaultGuard). If no guard was marked default - typically because the 'default' key is missing or false on every guard in config - calling guard(), or anything that delegates to it (id(), logout(), user()...), throws DefaultGuardNotRegistered.
Source
Thrown at phalcon/Auth/Manager.zep:153
return this->defaultGuard;
}
/**
* @return array<string, Guard>
*/
public function getGuards() -> array
{
return this->guards;
}
/**
* @throws Exception
*/
public function guard(string name = null) -> <Guard>
{
if (name === null) {
if (this->defaultGuard === null) {
throw new DefaultGuardNotRegistered();
}
return this->defaultGuard;
}
if (!isset(this->guards[name])) {
throw new GuardNotDefined(name);
}
return this->guards[name];
}
public function id() -> int | string | null
{
return this->guard()->id();
}
public function logout() -> voidView on GitHub (pinned to b7419de9cd)
Solutions
- Mark exactly one guard as default in config: guards: {web: {default: true, ...}, api: {...}}
- Or set it programmatically: $manager->setDefaultGuard($manager->guard('web'));
- Or always pass the guard name explicitly: $auth->guard('web')->user() instead of relying on a default
Example fix
// before
'guards' => [
'web' => ['adapter' => [...], 'type' => 'session'],
],
// after
'guards' => [
'web' => ['adapter' => [...], 'type' => 'session', 'default' => true],
], Defensive patterns
Strategy: validation
Validate before calling
$hasDefault = false;
foreach ($config['guards'] ?? [] as $guard) {
$hasDefault = $hasDefault || (bool) ($guard['default'] ?? false);
}
if (!$hasDefault) {
throw new InvalidArgumentException('Exactly one guard must be marked default: true');
} Try / catch
try {
$user = $auth->user();
} catch (\Phalcon\Auth\Exceptions\DefaultGuardNotRegistered $e) {
// fall back to an explicit guard name instead of relying on a default
$user = $auth->guard('web')->user();
} Prevention
- Always mark exactly one guard default: true in multi-guard configs
- Prefer explicit guard('name') calls in code so a missing default is not fatal
- Assert at boot that $manager->guard() (no args) returns without throwing
When it happens
Trigger: Auth config with guards: {web: {...}, api: {...}} but neither entry has default: true; calling $auth->user() / $auth->logout() / $auth->id() on a manager built from such config; constructing Manager manually and only calling addGuard() without ever calling setDefaultGuard().
Common situations: Multi-guard configs (web + api) where the author forgets to elect a default; config refactor that drops the 'default' flag; code written against a single guard assuming it is implicitly default.
Related errors
- Session guard 'name' and 'rememberName' must differ
- Auth guard '{name}' is not defined
- Unknown auth guard '{type}'
- Malformed ACL snapshot structure
- Stream adapter file does not exist: {path}
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/f4790d98fcbcf442.
Report an issue: GitHub.