BookStackApp/BookStack · error · OidcInvalidTokenException
Missing token subject value
Error message
Missing token subject value
What it means
The 'sub' (Subject) claim uniquely identifies the end user and is REQUIRED by the OIDC spec. As a custom check, validateTokenClaims throws when the token payload has no 'sub' value, because the application cannot attribute the session to any user.
Source
Thrown at app/Access/Oidc/OidcIdToken.php:86
}
$dayAgo = time() - 86400;
$iat = intval($this->payload['iat']);
if ($iat > ($now + $skewSeconds) || $iat < $dayAgo) {
throw new OidcInvalidTokenException('Token issue at time is not recent or is invalid');
}
// 7. If the acr Claim was requested, the Client SHOULD check that the asserted Claim Value is appropriate.
// The meaning and processing of acr Claim Values is out of scope for this document.
// NOTE: Not used for our case here. acr is not requested.
// 8. When a max_age request is made, the Client SHOULD check the auth_time Claim value and request
// re-authentication if it determines too much time has elapsed since the last End-User authentication.
// NOTE: Not used for our case here. A max_age request is not made.
// Custom: Ensure the "sub" (Subject) Claim exists and has a value.
if (empty($this->payload['sub'])) {
throw new OidcInvalidTokenException('Missing token subject value');
}
}
}
View on GitHub (pinned to 18f8469a1c)
Solutions
- Fix the IdP to include a non-empty 'sub' claim per OIDC Core spec
- Update test token fixtures to include 'sub'
- Check no proxy/middleware removes claims from the id_token
- Map the correct user identifier if the IdP uses a different claim and you control token minting
Example fix
// before (test fixture payload) ['iss' => $iss, 'aud' => $aud, 'exp' => time()+3600, 'iat' => time()] // after ['iss' => $iss, 'aud' => $aud, 'exp' => time()+3600, 'iat' => time(), 'sub' => 'user-123']
Defensive patterns
Strategy: validation
Validate before calling
if (empty($payload['sub'])) { throw new \RuntimeException('ID token missing sub claim'); } Try / catch
try { $token->validate($now); } catch (OidcInvalidTokenException $e) { if ($e->getMessage() === 'Missing token subject value') { /* reject login; report non-conformant IdP */ } throw $e; } Prevention
- Validate IdP conformance (sub is REQUIRED by OIDC Core)
- Keep test fixtures aligned with real token claims including sub
- Ensure no middleware strips claims from the id_token
When it happens
Trigger: validate() on an ID token whose payload lacks 'sub' or has it empty/null.
Common situations: Non-conformant IdP omitting subject; tokens generated by custom/legacy auth services; test fixtures missing 'sub'; claim-filtering middleware stripping the subject for privacy.
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
- Missing token issued at time value
- Missing token audience value
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/f7e64309f1149b1a.
Report an issue: GitHub.