invalid_grant error while making oidc token api call

Summary

A request to the /a/consumer/api/v0/oidc/token endpoint failed with an invalid_grant error. This indicates that the authorization code exchange was rejected by the OpenID Connect provider because one or more parameters in the token request were invalid, expired, mismatched, or previously used.

Root Cause

The invalid_grant error almost always means the OIDC provider refused the grant due to one of the following:

  • Authorization code already used (OIDC codes are single‑use)
  • Authorization code expired before the token request was made
  • Redirect URI mismatch between the authorization request and token request
  • PKCE code_verifier mismatch (incorrect, altered, or not tied to the original code_challenge)
  • Client credentials incorrect (wrong client_id or client_secret)
  • Grant type not allowed for the client configuration
  • Code issued to a different client than the one making the token request

Why This Happens in Real Systems

Real OIDC systems enforce strict validation rules to prevent token theft and replay attacks. Common real‑world triggers include:

  • Frontend and backend disagree on redirect URI
  • Mobile apps generating a new code_verifier instead of reusing the original one
  • Clock skew causing the provider to treat the code as expired
  • Developers reusing the same authorization code during testing
  • Misconfigured client settings in the identity provider console

Real-World Impact

When this error appears in production, it typically results in:

  • Users unable to log in
  • Mobile apps stuck in an authentication loop
  • Increased support tickets due to login failures
  • Failed integrations between backend services and identity providers

Example or Code (if necessary and relevant)

Below is a minimal, valid token exchange example for reference:

curl --location 'https://example.org/a/consumer/api/v0/oidc/token' \
  --header 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode 'code=AUTH_CODE_HERE' \
  --data-urlencode 'redirect_uri=https://your-app/callback' \
  --data-urlencode 'code_verifier=ORIGINAL_CODE_VERIFIER' \
  --data-urlencode 'client_id=CLIENT_ID' \
  --data-urlencode 'client_secret=CLIENT_SECRET'

How Senior Engineers Fix It

Experienced engineers approach this systematically:

  • Verify redirect URI matches exactly (character‑for‑character) the one used during authorization
  • Confirm the code_verifier is the same one used to generate the original code_challenge
  • Check that the authorization code is fresh and not reused
  • Validate client configuration in the identity provider (allowed grant types, redirect URIs, PKCE settings)
  • Inspect logs on both client and identity provider sides to correlate timestamps
  • Reproduce the flow manually to isolate where parameters diverge

Why Juniors Miss It

Less experienced engineers often overlook subtle but critical details:

  • They assume redirect URIs are “close enough” instead of exact string matches
  • They regenerate the PKCE code_verifier accidentally
  • They reuse authorization codes during testing
  • They don’t realize that identity provider settings override client assumptions
  • They focus on the error message instead of the full OIDC flow and its constraints

This error is frustrating but extremely common, and mastering it is a rite of passage for engineers working with OAuth2/OIDC.

Leave a Comment