Skip to main content
Version: 1.0

Error reference

This page lists every OAuth error code returned by PBAC endpoints, organized by endpoint. Each entry includes the HTTP status, common causes, and how to fix it.

Token endpoint (/token)

invalid_request (400)

CauseDetail
Missing/blank grant_typeEvery token request must include a grant type.
Blank authorization code or redirect_uriAuth code flow requires both values.
Missing scope when requiredSome grant types require an explicit scope.
PKCE code_challenge_method set to plainOnly S256 is allowed.
resource parameter contains a fragment (#)Resource URIs must not include fragments.
Malformed Basic auth headerHeader must be valid Base64-encoded client_id:client_secret.
Missing subject_token or subject_token_typeToken exchange requires both fields.
authorization_details JSON parsing failureRAR body must be valid JSON.

Fix: Check request parameters match the grant type requirements. Use S256 for PKCE. Remove fragments from resource URIs.

invalid_client (401)

CauseDetail
Client not foundThe client_id does not exist.
Client secret incorrectCredentials do not match.
Client disabled or revokedThe client has been deactivated via Admin API.
client_assertion JWT validation failureMissing sub, bad aud, expired, or signature mismatch.
Client not configured for private_key_jwt authThe client's token_endpoint_auth_method is not private_key_jwt.
No JWKS configured for the clientprivate_key_jwt requires a jwks_uri or inline jwks.

Fix: Verify client_id and client_secret. Check the client is enabled via Admin API. For private_key_jwt, verify JWKS configuration.

invalid_grant (400)

CauseDetail
Authorization code expiredCodes are valid for 10 minutes.
Authorization code already usedCodes are single-use.
Authorization code issued to a different clientThe client_id must match the original authorize request.
Redirect URI mismatchThe redirect_uri must match exactly between authorize and token requests.
PKCE code_verifier fails verificationThe verifier does not match the original code_challenge.
Refresh token expired or issued to different clientRefresh tokens are bound to the issuing client.
DPoP key mismatch for bound refresh tokenThe DPoP key must match the key used when the refresh token was issued.
Subject token invalid/expired in token exchangeThe presented subject token must be active.
ID token signature verification failureThe ID token's RS256 signature could not be verified against the IdP's JWKS.

Fix: Request a fresh authorization code. Ensure redirect_uri matches exactly. Verify PKCE code_verifier matches the original code_challenge. Request a new refresh token.

unauthorized_client (400)

CauseDetail
Public client attempting client_credentials or token_exchangeThese grants require confidential clients.

Fix: These grants require confidential clients. Register as confidential with a client secret.

unsupported_grant_type (400)

CauseDetail
Unrecognized grant typeMust be one of: client_credentials, authorization_code, refresh_token, urn:ietf:params:oauth:grant-type:token-exchange.

Fix: Use a supported grant type.

invalid_scope (400)

CauseDetail
Token exchange: requested scope exceeds subject token's granted scopeYou cannot escalate privileges via token exchange.

Fix: Request only scopes that were granted in the original token.

access_denied (400)

CauseDetail
OPA policy evaluation returned a DENY decisionThe error_description contains the policy reason (sanitized).

Fix: Check policy data (denylists, entitlements) and the client's software statement. The error_description often indicates the specific policy rule that denied the request.

invalid_target (400)

CauseDetail
Resource URI could not be resolved to a known resource typeThe resource parameter does not match any registered Resource Server URI.

Fix: Verify the resource parameter matches a registered Resource Server URI, or use resource_types with a known type URN.

invalid_authorization_details (400)

CauseDetail
RAR authorization_details contains an unknown or unregistered typeThe type must be registered in policy data.

Fix: Verify the RAR type is registered in policy data under resource.types.

use_dpop_nonce (400)

CauseDetail
DPoP proof missing or stale nonceThe response includes a DPoP-Nonce header with a fresh value.

Fix: Retry the request with the nonce from the DPoP-Nonce response header.

invalid_dpop_proof (400)

CauseDetail
DPoP proof JWT validation failedWrong typ, symmetric algorithm, missing jwk, private key in header, signature failure, htm/htu mismatch, expired iat, replayed jti, wrong ath.

Fix: Verify the DPoP proof follows RFC 9449 -- asymmetric key, typ: "dpop+jwt", correct htm and htu, fresh iat, unique jti.

server_error (500)

CauseDetail
Unhandled exception during token processingAn unexpected error occurred on the server.

Fix: Check AS logs for the stack trace. If reproducible, report to your PBAC administrator.

Introspect endpoint (/introspect)

invalid_token (401)

CauseDetail
Bearer token (PAT) not found or expiredThe PAT used to authenticate the introspect call is invalid.

Fix: Obtain a fresh PAT with uma_protection or introspection scope.

invalid_client (401)

CauseDetail
Basic auth failedClient not found, wrong secret, or client not entitled to uma_protection/introspection scope.

Fix: Verify RS client credentials and software statement includes urn:as:introspect with uma_protection scope.

Response: active: false (200)

This is not an error -- it means the token is inactive. Causes: token not found, expired, client disabled, or OPA re-evaluation denied access for the supplied context.

Fix: Request a fresh access token. Check that the token's client is still enabled and policy data hasn't changed.

Authorize endpoint (/authorize)

Errors redirect to the client's redirect_uri with error and error_description query parameters.

invalid_request

CauseDetail
response_type not codeOnly the authorization code flow is supported.
Missing client_id or redirect_uriBoth are required.
Redirect URI not HTTPS (or localhost)Production URIs must use HTTPS.
Redirect URI not registered for clientThe URI must match a registered redirect URI.
Public client missing PKCE code_challengePublic clients must include code_challenge with S256.

Fix: Use response_type=code. Register the redirect URI. Public clients must include code_challenge with S256.

invalid_client

CauseDetail
Client not found or disabledThe client_id does not exist or has been deactivated.

access_denied

CauseDetail
OPA policy denied the authorization requestCheck policy data and entitlements.

server_error

CauseDetail
IdP not configured or disabledThe identity provider for the client is missing or inactive.

Register endpoint (/register)

unapproved_software_statement (400)

CauseDetail
Policy denied registrationClient or issuer is on the denylist.

Fix: Check denylist.software_ids and denylist.domains in policy data.

invalid_software_statement (400)

CauseDetail
Untrusted issuerThe software statement's iss is not in trust.trusted_issuers.
Missing software statementRequired by policy but not provided.

Fix: Add the issuer to trust.trusted_issuers in policy data, or register without a software statement if public DCR is enabled.

invalid_client_metadata (400)

CauseDetail
private_key_jwt auth without jwks_uri or jwksKey material is required for this auth method.
jwks_uri not HTTPSThe JWKS endpoint must use HTTPS.

Fix: Provide a valid HTTPS jwks_uri or inline jwks.

invalid_redirect_uri (400)

CauseDetail
Redirect URI not absolute HTTPS or http://localhostProduction URIs require HTTPS. http://localhost is allowed for development.

Fix: Use https:// for production URIs. http://localhost is allowed for development.

Admin API

401 Unauthorized

CauseDetail
Missing or invalid X-Admin-API-Key headerEvery Admin API request must include the correct key.

Fix: Include the correct API key in the X-Admin-API-Key header.

400 Bad Request

CauseDetail
Validation failureResponse includes a fieldErrors map with specific field-level issues.

Fix: Check the fieldErrors object for specific field-level issues.

409 Conflict

CauseDetail
Duplicate resourceFor example, a client_id already exists.

Fix: Use a unique identifier, or use PUT to update the existing resource.

Next steps