# OAuth2 error: invalid_grant: Authorization code has expired

- **ID:** `api/oauth2-invalid-grant-authorization-code-expired`
- **Domain:** api
- **Category:** auth_error
- **Error Code:** `invalid_grant`
- **Verification:** ai_generated
- **Fix Rate:** 92%

## Root Cause

The authorization code used in the token exchange request was issued more than the allowed lifetime (typically 60-600 seconds) ago.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| OAuth 2.0 RFC 6749 | active | — | — |
| Auth0 2024 | active | — | — |
| Okta 2023 | active | — | — |
| Keycloak 22.0 | active | — | — |

## Workarounds

1. **Complete the authorization code exchange within the allowed window (typically 10 minutes). Automate the redirect-to-token flow without manual delays. Use PKCE to ensure the code verifier is fresh per request.** (95% success)
   ```
   Complete the authorization code exchange within the allowed window (typically 10 minutes). Automate the redirect-to-token flow without manual delays. Use PKCE to ensure the code verifier is fresh per request.
   ```
2. **If using a browser-based flow, ensure the callback endpoint immediately triggers the token exchange without user interaction that could cause delays.** (90% success)
   ```
   If using a browser-based flow, ensure the callback endpoint immediately triggers the token exchange without user interaction that could cause delays.
   ```

## Dead Ends

- **** — The same user session may return the same expired code if the state parameter is reused; the root cause is timing, not the code value. (70% fail)
- **** — Long-lived authorization codes violate OAuth 2.0 security best practices and may be rejected by client libraries; also the server may have a hard upper limit. (80% fail)
