BookStackApp/BookStack · error · IdentityProviderException
{$data['error'] ?? $response->getReasonPhrase()}
Error message
{$data['error'] ?? $response->getReasonPhrase()} What it means
This error comes from checkResponse in OidcOAuthProvider (BookStack's league/oauth2-client based provider). When the identity provider's token or authorization response has an HTTP status >= 400 or an 'error' key in the decoded body, an IdentityProviderException is thrown carrying either the provider-reported 'error' string or, if absent, the HTTP reason phrase (e.g. 'Internal Server Error'). It is the library's way of surfacing an OAuth/OIDC protocol-level rejection from the remote IdP.
Source
Thrown at app/Access/Oidc/OidcOAuthProvider.php:91
}
/**
* Returns the string that should be used to separate scopes when building
* the URL for requesting an access token.
*/
protected function getScopeSeparator(): string
{
return ' ';
}
/**
* Checks a provider response for errors.
* @throws IdentityProviderException
*/
protected function checkResponse(ResponseInterface $response, $data): void
{
if ($response->getStatusCode() >= 400 || isset($data['error'])) {
throw new IdentityProviderException(
$data['error'] ?? $response->getReasonPhrase(),
$response->getStatusCode(),
(string) $response->getBody()
);
}
}
/**
* Generates a resource owner object from a successful resource owner
* details request.
*/
protected function createResourceOwner(array $response, AccessToken $token): ResourceOwnerInterface
{
return new GenericResourceOwner($response, '');
}
/**
* Creates an access token from a response.View on GitHub (pinned to 18f8469a1c)
Solutions
- Read the IdentityProviderException body (3rd argument) and the provider's logs to see the exact OAuth error code returned.
- Verify APP/oidc client_id, client_secret and redirect URI exactly match the IdP application settings.
- Re-run the login flow from scratch (fresh authorize request) — invalid_grant errors are often caused by reusing a consumed code or stale session.
- Check the IdP status/health and confirm the issuer/token endpoints are reachable over HTTPS.
- Compare scopes requested against those allowed by the IdP application.
Example fix
// before: generic failure hard to debug
try { $token = $provider->getAccessToken('authorization_code', [...]); }
catch (IdentityProviderException $e) { Log::error($e->getMessage()); }
// after: log full body from provider for the real cause
try { $token = $provider->getAccessToken('authorization_code', [...]); }
catch (IdentityProviderException $e) {
Log::error('OIDC provider error: ' . $e->getMessage() . ' body: ' . $e->getResponseBody());
} Defensive patterns
Strategy: try-catch
Validate before calling
$body = json_decode((string) $response->getBody(), true);
if (($response->getStatusCode() >= 400 || isset($body['error']))) {
Log::warning('OIDC provider will reject this response', ['status' => $response->getStatusCode(), 'body' => $body]);
} Type guard
function isProviderError(ResponseInterface $response, ?array $data): bool {
return $response->getStatusCode() >= 400 || isset($data['error']);
} Try / catch
try {
$token = $provider->getAccessToken('authorization_code', ['code' => $code]);
} catch (IdentityProviderException $e) {
Log::error('OIDC token exchange failed', ['msg' => $e->getMessage(), 'body' => (string) $e->getResponseBody()]);
return back()->withErrors(['oidc' => 'Authentication with the identity provider failed.']);
} Prevention
- Triple-check client_id, client_secret and redirect URI against the IdP application config.
- Never reuse authorization codes; always start a fresh authorize round-trip on failure.
- Monitor IdP status and alert on repeated provider errors.
- Keep requested scopes within those permitted by the IdP.
When it happens
Trigger: Any OAuth2 exchange through OidcOAuthProvider (getAccessToken, resource owner fetch, etc.) where the remote OIDC provider returns HTTP >= 400, or returns 200 but includes an 'error' field in the JSON body (e.g. invalid_grant, invalid_client, unauthorized_client).
Common situations: Wrong client_id/client_secret in BookStack OIDC config causing invalid_client; expired or replayed authorization code causing invalid_grant; misconfigured redirect URI; IdP outage returning a 5xx; clock skew invalidating tokens.
AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02).
Data as JSON: /api/errors/e9ce99214e0117e0.
Report an issue: GitHub.