OAuth 2.0 Error: invalid_grant
The authorization code, refresh token or credentials sent to the token endpoint are invalid, expired, already used or were issued to a different client.
Meaning
invalid_grant is returned by the OAuth token endpoint (Google, Microsoft, Auth0, Okta, Salesforce…). The grant — the thing you exchange for tokens — is no longer acceptable. Authorization codes are single-use and short-lived (often 30–60 seconds to 10 minutes); refresh tokens can be revoked or expire.
Common causes
- Authorization code already used (double submit, page refresh, retries)
- Authorization code expired before exchange
redirect_uriin the token request differs from the one used in the authorize request- Refresh token revoked (password change, user removed app access, token limit exceeded)
- Google: app in “Testing” publishing status — refresh tokens expire after 7 days
- Server clock skew (JWT client assertions)
- PKCE
code_verifierdoesn’t match thecode_challenge
⚡ Quick fix
- Exchange the code exactly once, immediately after the redirect
- Use the byte-identical
redirect_uriin both requests - On refresh failure, send the user through login/consent again
- For Google apps in testing, publish the app or expect weekly re-consent
- Sync server time via NTP
Detailed fix by platform
- Check OAuth consent screen publishing status; refresh tokens for “Testing” apps last 7 days. Users can revoke access at myaccount.google.com/permissions.
Microsoft
- The
error_descriptioncontains an AADSTS code (e.g. AADSTS70008 = expired code, AADSTS50173 = grant revoked after password change).
How to diagnose
- Grant type — Authorization code or refresh token?
- Freshness — Was the code used once, quickly?
- redirect_uri — Identical in authorize and token requests?
- Revocation — Password change or user revoked consent?
- Description — Read error_description for provider-specific codes
🧠 Still stuck? Analyze your error
Paste the full message, response headers or stack trace — we'll detect the platform and point to the most likely cause.
Was this page helpful?
Report a correction or suggest an improvement
Last updated 2 Oct 2026