BookStackApp/BookStack · error · OidcException
{$exception->getMessage()}
Error message
{$exception->getMessage()} What it means
During OIDC login, BookStack calls registrationService->findOrRegister() to match or create the local user. If that throws a UserRegistrationException (registrations disabled, email domain not allowed, user already exists with different credentials, theme prevention, etc.), it is rethrown here as an OidcException with the same message.
Solutions
- Read the wrapped message in logs — it indicates the underlying registration failure
- If users should auto-provision, set REGISTRATION_ENABLED=true (or rely on external auth auto-registration path)
- Check email domain restrictions (APP via RegistrationService ensureEmailDomainAllowed config) allow the IdP user's domain
- If the email already exists locally, merge/rename the existing user or align credentials
- Check custom themes for AUTH_PRE_REGISTER handlers returning false
Example fix
// before (.env) REGISTRATION_ENABLED=false // after (allow OIDC auto-registration) REGISTRATION_ENABLED=true
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check the conditions registerUser enforces:
// 1) registration allowed, 2) email domain allowed, 3) no existing user with email
$existing = \BookStack\Users\UserRepo::new()->getByEmail($email);
if ($existing !== null) { /* account conflict — resolve before login */ }
// Confirm REGISTRATION_ENABLED=true if auto-provisioning is expected Try / catch
try {
auth()->attemptOidcLogin();
} catch (BookStack\Access\Oidc\OidcException $e) {
Log::warning('OIDC registration rejected', ['reason' => $e->getMessage()]);
return redirect('/login')->withErrors(['oidc' => $e->getMessage()]);
} Prevention
- Enable REGISTRATION_ENABLED if new users must auto-provision
- Keep email-domain restriction lists in sync with your IdP domains
- Audit themes/plugins hooking AUTH_PRE_REGISTER for accidental vetoes
- Pre-provision or link accounts for users known to exist locally
When it happens
Trigger: processAccessTokenCallback -> findOrRegister(name, email, externalId) throws UserRegistrationException; this wrapper forwards $exception->getMessage() as an OidcException.
Common situations: REGISTRATION_ENABLED=false with a user whose email doesn't match an existing account, APP/registration email-domain restrictions (.env REGISTRATION_CONFIRM... / email domain whitelist) rejecting the domain, an existing BookStack user already has that email but signed in via different credentials, or a theme plugin hooking AUTH_PRE_REGISTER returning false.
Related errors
- errors.error_user_exists_different_creds
- A "n" parameter on the provided key is expected
- An "e" parameter on the provided key is expected
- auth.email_confirm_send_error
- auth.registration_email_domain_invalid
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/3c2e6c987bd56563.
Report an issue: GitHub.
Appendix: source
Thrown at app/Access/Oidc/OidcService.php:228
throw new OidcException(trans('errors.oidc_no_email_address'));
}
if (empty($userDetails->name)) {
$userDetails->name = $userDetails->externalId;
}
$isLoggedIn = auth()->check();
if ($isLoggedIn) {
throw new OidcException(trans('errors.oidc_already_logged_in'));
}
try {
$user = $this->registrationService->findOrRegister(
$userDetails->name,
$userDetails->email,
$userDetails->externalId
);
} catch (UserRegistrationException $exception) {
throw new OidcException($exception->getMessage());
}
if ($this->config()['fetch_avatar'] && !$user->avatar()->exists() && $userDetails->picture) {
$this->userAvatars->assignToUserFromUrl($user, $userDetails->picture);
}
if ($this->shouldSyncGroups()) {
$detachExisting = $this->config()['remove_from_groups'];
$this->groupService->syncUserWithFoundGroups($user, $userDetails->groups ?? [], $detachExisting);
}
$this->loginService->login($user, 'oidc');
return $user;
}
/**
* @throws OidcExceptionView on GitHub (pinned to 18f8469a1c)