BookStackApp/BookStack · error · OidcException
ID token validation failed with error: {$exception->getMessa
Error message
ID token validation failed with error: {$exception->getMessage()} What it means
BookStack's OIDC service throws this OidcException when the ID token returned by the identity provider fails local validation ($idToken->validate($settings->clientId)). Validation covers signature, issuer, audience, and expiry claims. The inner OidcInvalidTokenException message is wrapped to tell you exactly which check failed.
Source
Thrown at app/Access/Oidc/OidcService.php:205
$returnClaims = Theme::dispatch(ThemeEvents::OIDC_ID_TOKEN_PRE_VALIDATE, $idToken->getAllClaims(), [
'access_token' => $accessToken->getToken(),
'expires_in' => $accessToken->getExpires(),
'refresh_token' => $accessToken->getRefreshToken(),
]);
if (!is_null($returnClaims)) {
$idToken->replaceClaims($returnClaims);
}
if ($this->config()['dump_user_details']) {
throw new JsonDebugException($idToken->getAllClaims());
}
try {
$idToken->validate($settings->clientId);
} catch (OidcInvalidTokenException $exception) {
throw new OidcException("ID token validation failed with error: {$exception->getMessage()}");
}
$userDetails = $this->getUserDetailsFromToken($idToken, $accessToken, $settings);
if (empty($userDetails->email)) {
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,View on GitHub (pinned to 18f8469a1c)
Solutions
- Check OIDC_ISSUER, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET in .env match the IdP exactly (no trailing slash mismatch on issuer)
- Clear any cached OIDC discovery/JWKS data and restart so fresh signing keys are fetched
- Verify server clock is synchronized (ntp/chrony) — skew can cause expiry/iat validation failures
- Check the wrapped exception message in logs — it names the exact failed validation check
- Confirm APP_URL and redirect URI are consistent so token audience checks pass
Example fix
// before (wrong issuer, trailing slash) OIDC_ISSUER=https://idp.example.com/ // after (must exactly match the IdP's issuer claim) OIDC_ISSUER=https://idp.example.com
Defensive patterns
Strategy: validation
Validate before calling
// Before login, sanity-check env config matches the IdP
$checks = [
'OIDC_ISSUER' => env('OIDC_ISSUER'),
'OIDC_CLIENT_ID' => env('OIDC_CLIENT_ID'),
];
foreach ($checks as $k => $v) {
if (empty($v)) { throw new RuntimeException("$k must be set"); }
}
// Ensure server clock is synced and issuer has no trailing-slash mismatch
// php -r 'echo time();' vs IdP 'iat'/'exp'; ntpdate/chrony if skewed Try / catch
try {
auth()->attemptOidcLogin();
} catch (BookStack\Access\Oidc\OidcException $e) {
Log::error('OIDC login failed', ['msg' => $e->getMessage()]);
abort(401, 'OIDC token validation failed — check OIDC_ISSUER/CLIENT_ID and server clock');
} Prevention
- Keep OIDC_ISSUER byte-exact (watch trailing slashes) with the IdP's issuer claim
- Run NTP/chrony so server clock skew stays minimal
- Monitor IdP signing-key rotation and ensure discovery/JWKS is re-fetched
- Test OIDC login after every IdP config change in staging
When it happens
Trigger: During processAccessTokenCallback, the JWT received from the OIDC provider fails signature verification, has an iss that does not match the configured issuer, has aud that does not match the configured client_id, or is expired/not-yet-valid.
Common situations: Wrong APP_URL or issuer mismatch, wrong client_id/audience in .env, provider rotated signing keys (e.g. after key rotation or container restart with stale cached discovery/JWKS), clock skew between server and IdP.
Related errors
- Token audience value has ' . count($aud) . ' values, Expecte
- Token authorized party exists but does not match the expecte
- Missing token expiration time value
- Token has expired
- Missing token issued at time value
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/98f1ef1191fe0f8a.
Report an issue: GitHub.