google.auth.exceptions.RefreshError: invalid_grant: Token has been expired or revoked
Fixes Google OAuth refresh tokens that no longer work. Use when google-auth raises RefreshError with invalid_grant. Not for initial consent-screen setup problems.
TL;DR: Your refresh token is dead: revoked, expired, or invalidated by an account change. Delete the stored token and re-run the OAuth consent flow to get a new one. There is no way to resurrect the old token.
google.auth.exceptions.RefreshError: ('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been expired or revoked.'})Fix it
- Delete the stored credentials file (often token.json or wherever your app caches it). Expected: the file is gone.
- Re-run your app's auth flow and complete the consent screen again. Expected: a fresh token file is written.
- Retry the API call. Expected: success.
- If it recurs every 7 days, your OAuth app is in testing mode; publish it or switch to a service account for server workloads.
When this applies
- The error is RefreshError with invalid_grant and the token used to work.
When it doesn't
- The error is invalid_client: your client id/secret is wrong.
- You never completed the flow: that is a setup problem, not a dead token.
Compatibility
- google-auth / google-auth-oauthlib any version.
Why it happens
Refresh tokens die when the user revokes access, changes their password, or when a test-mode OAuth app's tokens hit the 7-day limit. The library cannot distinguish these; it just reports invalid_grant.
Edge cases
- Service accounts do not use refresh tokens; if you see this with one, check the key file instead.
- Multiple apps sharing one token file can revoke each other; keep token files per app.
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.