Skip to main content
Version 0.4Draft

OAuth and OIDC error codes

When LuxID rejects a request, it returns a structured error per RFC 6749 (opens in a new tab), OIDC Core 1.0 (opens in a new tab), and RFC 6750 (opens in a new tab). This page is the reference catalogue: for each error code you will find the governing specification, the most common LuxID-specific cause, and the canonical fix.

Three endpoints can return errors:

  • Authorization endpoint - https://login.luxid.lu/mga/sps/oauth/oauth20/authorize
  • Token endpoint - https://login.luxid.lu/mga/sps/oauth/oauth20/token
  • UserInfo / resource servers - any endpoint that accepts a Bearer token

Error code index

Error codeEndpointDetails
invalid_requestAuthorizationJump to section
unauthorized_clientAuthorizationJump to section
access_deniedAuthorizationJump to section
unsupported_response_typeAuthorizationJump to section
invalid_scopeAuthorizationJump to section
server_errorAuthorizationJump to section
temporarily_unavailableAuthorizationJump to section
interaction_requiredAuthorization (OIDC)Jump to section
login_requiredAuthorization (OIDC)Jump to section
account_selection_requiredAuthorization (OIDC)Jump to section
consent_requiredAuthorization (OIDC)Jump to section
invalid_request_uriAuthorization (OIDC)Jump to section
invalid_request_objectAuthorization (OIDC)Jump to section
request_not_supportedAuthorization (OIDC)Jump to section
request_uri_not_supportedAuthorization (OIDC)Jump to section
registration_not_supportedAuthorization (OIDC)Jump to section
invalid_requestTokenJump to section
invalid_clientTokenJump to section
invalid_grantTokenJump to section
unauthorized_clientTokenJump to section
unsupported_grant_typeTokenJump to section
invalid_scopeTokenJump to section
invalid_requestBearer (UserInfo / resource)Jump to section
invalid_tokenBearer (UserInfo / resource)Jump to section
insufficient_scopeBearer (UserInfo / resource)Jump to section

Authorization endpoint errors

Errors returned at the authorization endpoint follow RFC 6749 §4.1.2.1 (opens in a new tab) and OIDC Core 1.0 §3.1.2.6 (opens in a new tab). LuxID appends the error and error_description as query parameters on your registered redirect_uri:

https://app.example/callback?error=invalid_request&error_description=Missing+response_type&state=abc123

invalid_request

Specification: RFC 6749 §4.1.2.1

Description: The request is missing a required parameter, contains an invalid parameter value, or is otherwise malformed.

Common causes at LuxID:

  • response_type parameter is absent.
  • client_id is absent or does not correspond to any registered Application.
  • redirect_uri is absent when more than one redirect URI is registered for the Application.
  • A parameter appears more than once in the request.
  • code_challenge_method is present but code_challenge is absent (partial PKCE request).

Fix: Log the full error_description returned by LuxID - it names the missing or invalid parameter. Validate your authorization URL construction before retrying.

Sample redirect:

https://app.example/callback
?error=invalid_request
&error_description=Missing+required+parameter%3A+response_type
&state=abc123

unauthorized_client

Specification: RFC 6749 §4.1.2.1

Description: The client is not authorised to request an authorization code using this method.

Common causes at LuxID:

  • The Application's grant_types configuration with LuxID does not include authorization_code.
  • The Application type is machine-to-machine (client credentials only) and is being used in a browser flow.

Fix: Contact us to verify that Authorization Code is listed under your Application's allowed grant types. If the Application is purely server-to-server, register a separate Application for the user-facing flow.

Sample redirect:

https://app.example/callback
?error=unauthorized_client
&error_description=Client+is+not+authorized+to+use+this+grant+type
&state=abc123

access_denied

Specification: RFC 6749 §4.1.2.1

Description: The resource owner or LuxID denied the request.

Common causes at LuxID:

  • The user clicked Cancel or Deny on the LuxID Universal Login consent screen. This is a normal, expected code path - not an error in your integration.
  • LuxID's risk engine blocked the authentication attempt (unusual location, suspected automated activity).

Fix: access_denied from user cancellation is expected behaviour and must be handled gracefully. Show the user a message such as "Sign-in was cancelled. You can try again at any time." Do not treat it as a fatal error. If you believe the error is risk-engine related rather than user-initiated, inspect the error_description and contact LuxID.

Sample redirect:

https://app.example/callback
?error=access_denied
&error_description=User+denied+access
&state=abc123

unsupported_response_type

Specification: RFC 6749 §4.1.2.1

Description: The authorization server does not support obtaining an authorization code using the requested response_type.

LuxID supported values:

ValueUse
codeStandard Authorization Code flow (recommended for all clients)
noneUsed with prompt=none to silently check session state without issuing tokens

Common causes at LuxID:

  • response_type=token (Implicit flow) - LuxID does not support the Implicit flow. Migrate to Authorization Code with PKCE.
  • response_type=id_token or response_type=code id_token (Hybrid flow) - not supported.
  • Typo in the parameter value.

Fix: Use response_type=code together with PKCE (code_challenge + code_challenge_method=S256).

Sample redirect:

https://app.example/callback
?error=unsupported_response_type
&error_description=response_type+token+is+not+supported
&state=abc123

invalid_scope

Specification: RFC 6749 §4.1.2.1

Description: The requested scope is invalid, unknown, or exceeds the scope granted by the resource owner.

LuxID supported scopes:

ScopeClaims returned
openidRequired for OIDC; triggers ID Token issuance
profilename, given_name, family_name, birthdate, nickname, updated_at
emailemail, email_verified
phonephone_number, phone_number_verified
offline_accessIssues a refresh token

Common causes at LuxID:

  • openid is absent. Every OIDC request must include openid.
  • A proprietary or undefined scope string is requested (e.g. read:messages).
  • The Application is not configured to grant offline_access but the scope is requested.

Fix: Start with scope=openid profile email and add offline_access only if your Application is configured for refresh tokens with LuxID.

Sample redirect:

https://app.example/callback
?error=invalid_scope
&error_description=Scope+read%3Amessages+is+not+permitted
&state=abc123

server_error

Specification: RFC 6749 §4.1.2.1

Description: The authorization server encountered an unexpected condition that prevented it from fulfilling the request.

Common causes at LuxID:

  • Transient internal fault. Typically self-resolving within seconds.
  • Misconfigured Application record (rare; usually caught at registration time).

Fix: Retry with exponential back-off. If the error persists beyond a few minutes, contact LuxID with the error_description and the approximate time of the failure.

Sample redirect:

https://app.example/callback
?error=server_error
&error_description=An+unexpected+error+occurred
&state=abc123

temporarily_unavailable

Specification: RFC 6749 §4.1.2.1

Description: The authorization server is temporarily unable to handle the request due to maintenance or overload.

Common causes at LuxID:

  • Scheduled maintenance window.
  • Transient overload condition.

Fix: Implement retry logic with exponential back-off and jitter. Respect Retry-After headers if present. Display a user-facing message: "Sign-in is temporarily unavailable. Please try again in a moment."

Sample redirect:

https://app.example/callback
?error=temporarily_unavailable
&error_description=Service+is+temporarily+unavailable
&state=abc123

OIDC-specific authorization errors

These codes extend RFC 6749 and are defined in OIDC Core 1.0 §3.1.2.6 (opens in a new tab). They are only returned when openid is included in the scope.

interaction_required

Description: The authorization server requires end-user interaction. Returned when prompt=none was sent but LuxID cannot complete authentication silently.

Common causes at LuxID:

  • The user has no active LuxID session.
  • The user's session exists but requires MFA re-verification before the requested scope can be granted.
  • The Application requires a higher assurance level than the current session provides.

Fix: Detect interaction_required and initiate a full interactive authorization flow (i.e., redirect the user to the authorization endpoint without prompt=none). Never surface this error code directly to the user.

Sample redirect:

https://app.example/callback
?error=interaction_required
&error_description=User+interaction+is+required
&state=abc123

login_required

Description: The authorization server requires end-user authentication. Returned when prompt=none was sent and there is no active session.

Common causes at LuxID:

Fix: Fall back to a full interactive login. This is the expected signal for silent-renewal failure.


account_selection_required

Description: The user has multiple sessions and must select one, but prompt=none prevented the selection screen from appearing.

Common causes at LuxID:

  • Not commonly encountered in the current LuxID deployment, as LuxID is a single-account IdP. If received, it indicates a session ambiguity that requires user interaction.

Fix: Remove prompt=none and allow the interactive flow to present account selection.


Description: The authorization server requires the user to consent to the requested scopes, but prompt=none prevented the consent screen from appearing.

Common causes at LuxID:

Fix: Remove prompt=none. If you need to rely on silent flows, ensure you have requested consent interactively at least once before using prompt=none.


invalid_request_uri

Description: The request_uri in the authorization request returns an error or contains invalid data.

Common causes at LuxID:

  • JAR (JWT-Secured Authorization Requests) with request_uri is not supported by LuxID. Use standard query parameters instead.

Fix: Remove request_uri from your authorization request. Contact LuxID if your integration requires JAR support.


invalid_request_object

Description: The request parameter contains an invalid JWT.

Common causes at LuxID:

  • Malformed JWT structure in the request parameter.
  • JWT signed with a key not registered for the Application.

Fix: Validate your request object JWT independently before sending. Confirm the signing key matches what is registered with LuxID.


request_not_supported

Description: The request parameter is not supported by this Application type.

Fix: Use standard OAuth 2.0 query parameters instead of a JWT request object.


request_uri_not_supported

Description: The request_uri parameter is not supported.

Common causes at LuxID:

  • request_uri is not supported for any Application type at LuxID.

Fix: Remove request_uri and use standard query parameters.


registration_not_supported

Description: Dynamic client registration is not supported.

Common causes at LuxID:

  • LuxID does not support dynamic client registration (RFC 7591 (opens in a new tab)). All Applications must be registered via LuxID or the onboarding process.

Fix: Register your Application via Configure LuxID, or contact LuxID to initiate the onboarding process.


Token endpoint errors

Token endpoint errors are returned as JSON in the response body with HTTP status 400 or 401, per RFC 6749 §5.2 (opens in a new tab):

{
"error": "invalid_grant",
"error_description": "Refresh token has expired"
}

invalid_request

Specification: RFC 6749 §5.2

Description: The request is missing a required parameter or is otherwise malformed.

Common causes at LuxID:

  • grant_type is absent.
  • code is absent on an authorization_code request.
  • refresh_token is absent on a refresh_token request.
  • code_verifier is absent when PKCE was used in the authorization request.
  • The Content-Type header is not application/x-www-form-urlencoded.

Fix: Ensure the request body is form-encoded (Content-Type: application/x-www-form-urlencoded) and all required parameters are present. For PKCE, always include code_verifier.

Sample response:

{
"error": "invalid_request",
"error_description": "Missing required parameter: code_verifier"
}

invalid_client

Specification: RFC 6749 §5.2

HTTP status: 400 (LuxID returns 400, not the 401 that RFC 6749 also permits)

Description: Client authentication failed - the Client ID or Client Secret is incorrect, the client is unknown, or the authentication method does not match what is configured.

Common causes at LuxID:

  • UAT Client ID or Secret used against the production token endpoint (https://login.luxid.lu/mga/sps/oauth/oauth20/token) or vice versa.
  • Client Secret has been rotated in the Console but the application is still using the old value.
  • client_id and client_secret are being sent in the request body when the Application is configured for Authorization: Basic, or vice versa.
  • The Application is a public client (no secret) but a secret is being sent.

Fix:

  1. Verify that your client_id matches the environment you are targeting (UAT vs. production - login-uat.luxid.lu vs. login.luxid.lu).
  2. Check whether the Client Secret has been rotated recently with LuxID.
  3. Confirm the authentication method: use Authorization: Basic base64(client_id:client_secret) for confidential clients unless the Console specifies client_secret_post.

Sample response:

{
"error": "invalid_client",
"error_description": "FBTOAU203E The client identifier could not be found."
}

Other observed error_description values: FBTOAU229E Confidential clients accessing the token endpoint must authenticate using their registered credentials. (no client authentication sent) and FBTOAU204E An invalid client assertion or client secret was provided for the client identifier. (wrong secret).


invalid_grant

Specification: RFC 6749 §5.2

Description: The authorization code, refresh token, or PKCE verifier is invalid, expired, or does not match.

Common causes at LuxID:

  • Authorization code already used - codes are single-use. A replay attempt (e.g., browser back button, duplicate POST) will fail.
  • Authorization code expired - codes are short-lived (typically 60 seconds). Long network delays or slow backend processing can cause expiry.
  • Refresh token expired - LuxID refresh tokens have a rolling inactivity window. If the token has not been used within that window, it is invalidated.
  • Refresh token revoked by user - the user revoked application access from https://account.luxid.lu/ (opens in a new tab) under Applications. All refresh tokens for that Application are immediately invalidated.
  • PKCE verifier mismatch - the code_verifier sent to the token endpoint does not match the code_challenge sent at the authorization endpoint. This is the most common PKCE implementation error.
  • Cross-environment code - an authorization code issued by login-uat.luxid.lu cannot be exchanged at login.luxid.lu.

Fix:

  • For expired or already-used codes: initiate a new authorization request. Do not retry code exchange.
  • For revoked refresh tokens: force an interactive re-login and obtain a new refresh token.
  • For PKCE mismatch: verify your code_verifier derivation. The verifier must be the exact same random string used to compute code_challenge = BASE64URL(SHA256(ASCII(code_verifier))). Ensure no URL-encoding or trimming occurs between the two operations.
  • For cross-environment: confirm that client_id, token endpoint URL, and authorization endpoint URL all target the same environment.

Sample response:

{
"error": "invalid_grant",
"error_description": "FBTOAU211E The [authorization_grant] received of type [authorization_code] does not exist."
}

For a bad or expired refresh token the [type] in the message is [refresh_token] instead. (FBTOAU211E is the same code the UserInfo endpoint returns for a non-existent access token - the [type] distinguishes the case.)


unauthorized_client

Specification: RFC 6749 §5.2

Description: The authenticated client is not authorised to use this grant type.

Common causes at LuxID:

  • The Application is not configured for refresh_token grant but grant_type=refresh_token is being sent.
  • The Application is not configured for client_credentials grant but grant_type=client_credentials is being sent.

Fix: Open the Application with LuxID and verify that the required grant type is enabled under Allowed Grant Types.

Sample response:

{
"error": "unauthorized_client",
"error_description": "Client is not authorized to use grant type: refresh_token"
}

unsupported_grant_type

Specification: RFC 6749 §5.2

Description: The grant_type value is not recognised or not supported by LuxID.

LuxID supported grant types (per grant_types_supported in the discovery document):

  • authorization_code
  • refresh_token

Common causes at LuxID:

  • grant_type=client_credentials (machine-to-machine) - not supported. For server-to-server access, use the Partner API, which authenticates with X-Client-Id / X-Client-Secret headers rather than an OAuth grant.
  • grant_type=password (Resource Owner Password Credentials) - not supported.
  • grant_type=urn:ietf:params:oauth:grant-type:device_code (Device Code flow) - not supported.
  • grant_type=urn:ietf:params:oauth:grant-type:token-exchange (RFC 8693) - not supported.
  • Typo in the grant_type value.

Fix: Use only the supported grant types listed above.

Sample response:

{
"error": "unsupported_grant_type",
"error_description": "FBTOAU215E The grant type is not supported."
}

invalid_scope

Specification: RFC 6749 §5.2

Description: The requested scope is invalid or exceeds the scope of the original authorization.

Common causes at LuxID:

  • Requesting a scope during token refresh that was not granted in the original authorization. The scope of a refresh token cannot be expanded - only narrowed.
  • Requesting a scope that is not in the discovery document's scopes_supported (openid, profile, email, phone, offline_access).

Fix: When refreshing tokens, either omit the scope parameter (to reuse the original scope) or request a subset of the original scope.

Sample response:

{
"error": "invalid_scope",
"error_description": "Requested scope exceeds the scope granted by the user"
}

Bearer token errors

Bearer token errors are returned by resource server endpoints - including the UserInfo endpoint at https://login.luxid.lu/mga/sps/oauth/oauth20/userinfo - per RFC 6750 (opens in a new tab). They appear in the WWW-Authenticate response header and optionally in the JSON body:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="LuxID",
error="invalid_token",
error_description="The access token has expired"

invalid_request

Specification: RFC 6750 §3.1

HTTP status: 400

Description: The request is malformed - the access token is missing or sent in an invalid way.

Common causes at LuxID:

  • The Authorization: Bearer <token> header is absent.
  • The token appears both in the header and as a query parameter (duplication).
  • The Authorization header value is malformed (e.g., the Bearer keyword is missing or misspelt).

Fix: Send the access token exclusively in the Authorization header:

Authorization: Bearer eyJhbGciOiJSUzI1NiIs...

Sample response:

{
"error": "invalid_request",
"error_description": "Access token is missing"
}

invalid_token

Specification: RFC 6750 §3.1

HTTP status: 401

Description: The access token is expired, revoked, or has an invalid signature.

Common causes at LuxID:

  • Token expired - LuxID access tokens are short-lived. Check the exp claim and refresh before expiry using the refresh token.
  • Token revoked - the user revoked application access from https://account.luxid.lu/ (opens in a new tab). All tokens for the Application are immediately invalidated.
  • Signature invalid - the token has been tampered with, or your server is validating against stale JWKS. Refresh JWKS from https://login.luxid.lu/mga/sps/oauth/oauth20/jwks/OIDC-LUXID.
  • Wrong environment - a UAT access token used against a production resource server, or vice versa.

Fix:

  • On invalid_token, attempt to refresh using your refresh token. If the refresh also fails with invalid_grant, force re-authentication.
  • Cache JWKS with a short TTL (e.g., 15 minutes) and refresh on key-not-found rather than on every request. See Token validation issues for JWKS rotation handling.

Sample response:

{
"error": "invalid_token",
"error_description": "FBTOAU211E The [access_token] received of type [bearer] does not exist."
}

The error_description text varies by cause (for example, an expired token reports an expiry message). The FBTOAU prefix is an internal code prefix used by LuxID's identity platform. Note that the UserInfo endpoint returns this as a JSON body; a WWW-Authenticate header is not always present.


insufficient_scope

Specification: RFC 6750 §3.1

HTTP status: 403

Description: The access token does not have the scopes required by the resource server.

Common causes at LuxID:

  • Calling the UserInfo endpoint with a token that does not include the openid scope.
  • Calling an endpoint that requires email or phone scope, but those were not requested during authorization.

Fix: Ensure that all required scopes are included in the initial authorization request. If the user has already authorized without the required scope, initiate a new authorization flow with the additional scopes and present the consent screen explicitly.

Sample response:

{
"error": "insufficient_scope",
"error_description": "The access token does not contain the required scope: email"
}

Quick diagnostic flow

Use this flowchart to route yourself to the right section based on the error you are seeing.

For token validation failures (signature, issuer, audience, expiry, nonce), see Token validation issues.

For redirect URI errors (redirect_uri_mismatch), see Redirect and domain issues.

Updated 2026-07-03