Match on the error code (standard OAuth). The error_description text belongs to the engine and can change.
| Symptom | Cause | Fix |
|---|
Back at the app with error=invalid_scope | a scope outside the contract: phone, roles, offline_access, address… | request exactly openid profile email |
Back at the app with error=invalid_request about code_challenge_method | no PKCE, or plain | generate the PKCE pair; send code_challenge_method=S256 |
| IdP error page (HTTP 400), no return to the app | redirect_uri is not exactly a registered one: trailing slash, port, http for https, another path | use the descriptor’s exact value, or change the descriptor by pull request |
| Error page: client not found | wrong client_id, or the descriptor is not applied yet | check the client_id; after the merge, the IdP administration applies the clients |
Back at the app with error=unauthorized_client | response_type=token (implicit flow) | use response_type=code |
| Sign-in without a password prompt | an existing session at the IdP (single sign-on) | expected |
| Symptom | Cause | Fix |
|---|
Token endpoint answers 401 unauthorized_client | wrong secret, or the old one after a rotation | check the secret delivered for this environment |
400 invalid_grant on the code exchange | code used or expired, redirect_uri differs from the request’s, or code_verifier does not match the challenge | a code works once; start the login again |
400 invalid_grant on the refresh | the central session ended: account blocked, logout, 30 min idle, the 10 h ceiling, or an IdP restart | destroy the local session; answer 401; the person signs in again |
400 unauthorized_client for grant_type=password | the password grant is disabled | use Authorization Code with PKCE |
| Many sessions end at once | the IdP restarted | expected: every session ends within 5 minutes |
| Symptom | Cause | Fix |
|---|
| IdP error page (HTTP 400), no return to the app | post_logout_redirect_uri is not in postLogoutRedirectUris | add it to the descriptor |
| Next login after logout gets in without a password | the app ended only its local session | also redirect to end_session_endpoint with id_token_hint |
| Symptom | Cause | Fix |
|---|
ID token validation fails on iss | the app points to another issuer (a test environment, an old address) | use the permanent issuer |
nonce missing or mismatched | the library did not send a nonce | send one; some libraries do it only when asked |
| API answers 401 to a token that works in the app | another client’s token (different aud), an ID token, or expired | send the app’s own access token; refresh it on expiry |
| API finds no name and email claims | not in the access token | call userinfo_endpoint with the access token |
| Invited person signs in and gets no access | email_verified is false, or the invitation’s email differs | the person verifies the email at the IdP; compare emails case-insensitively |