invalid_grant 🔐 Authentication

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.

Seen on: Google Microsoft REST API

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_uri in 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_verifier doesn’t match the code_challenge

⚡ Quick fix

  1. Exchange the code exactly once, immediately after the redirect
  2. Use the byte-identical redirect_uri in both requests
  3. On refresh failure, send the user through login/consent again
  4. For Google apps in testing, publish the app or expect weekly re-consent
  5. Sync server time via NTP

Detailed fix by platform

Google

  1. Check OAuth consent screen publishing status; refresh tokens for “Testing” apps last 7 days. Users can revoke access at myaccount.google.com/permissions.

Microsoft

  1. The error_description contains an AADSTS code (e.g. AADSTS70008 = expired code, AADSTS50173 = grant revoked after password change).

How to diagnose

  1. Grant type — Authorization code or refresh token?
  2. Freshness — Was the code used once, quickly?
  3. redirect_uri — Identical in authorize and token requests?
  4. Revocation — Password change or user revoked consent?
  5. 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.