Identity server
Troubleshooting
Diagnose discovery, OAuth, audience, scope, and permission failures.
Start with the live API explorer or the embedded API reference. Record the endpoint, HTTP status, OAuth error or permission reason, environment, and request correlation ID when available. Remove tokens, codes, API keys, cookies, and client secrets before sharing a request.
Connection and token errors
| Symptom | Check |
|---|---|
Discovery returns 404 | Use https://dev.auth.graphxserver.io/.well-known/openid-configuration. The development deployment does not serve OIDC discovery at /api/auth/.well-known/openid-configuration. |
| Issuer validation fails | Compare the discovered issuer to the verifier configuration exactly. The development issuer has no /api/auth suffix. |
| Redirect URI mismatch | Compare the registered URI and request URI character for character. Use the same URI during code exchange. |
invalid_client | Check environment, secret rotation, and the registered token endpoint authentication method. A portal public flag alone does not configure none. |
invalid_grant | Check code reuse, transaction expiry, PKCE verifier, redirect URI, or a revoked or replaced refresh token. Start a new sign-in transaction when necessary. |
invalid_scope | Check the configured OAuth scope list, client allowance, resource policy, and machine scope allowance for userless grants. Scope names are case-sensitive. |
invalid_target | Check the registered resource URI. For API key exchange, send one resource and omit audience. |
API returns 401 | Check access token expiry, trusted signing keys, exact issuer, and API audience. Ensure the credential is an access token. |
API returns 403 | Check the endpoint's required scopes, organization policy, client restrictions, and user permissions. |
| Browser reports CORS or an origin error | Ask the service owner to approve the calling origin where required. Test the same request from a backend to distinguish browser policy from OAuth errors. Keep confidential credentials on the backend. |
Inspect token claims only in trusted local tooling, and treat them as untrusted until verification succeeds. Do not paste credentials into a public JWT decoder.
Organization and permission errors
| Symptom | Check |
|---|---|
NO_ACTIVE_ORGANIZATION | Include an organization scope in sign-in and complete organization selection. Obtain a token for the intended organization. |
A check returns 200 but the operation is denied | Inspect allowed. A permission refusal is represented in the JSON body. |
deny_unknown_permission | Check the registered full key and plane. OAuth scopes do not create permission definitions. |
deny_plane_mismatch | Check whether the action is suite-wide or organization-scoped. |
deny_application_inactive | Ask the administrator to check the permission catalog application's status. |
deny_not_member | Check current membership in the token's organization. Selecting another organization in the UI does not alter an issued token. |
UNSUPPORTED_SUBJECT | Use a user-delegated token for user checks. Client credentials and organization API key exchanges require service authorization rules. |
| Updated roles have no effect | Check the response's enforcement mode and the permission's configuration. Avoid long-lived application caches of authorization answers. |
Verify an integration before release
- A fresh authorization-code flow completes with state, nonce, and S256 PKCE validation.
- The API accepts a valid token for its audience and required scopes.
- Missing, expired, incorrectly signed, and wrong-audience tokens fail with
401. - A valid token without the required scope or user permission fails with
403. - A request cannot access a record in another organization by changing a route, body, or header.
- Renewal stores replacement credentials correctly and a failed renewal returns the user to sign-in.
- The application's documented logout and revocation behavior matches what you observe at each API.
For protocol details, see Better Auth's OAuth provider guide, session management, and OpenAPI plugin.