OAuth Refresh Token Expired โ How to Handle It
Updated April 2026
A refresh token expires silently โ your app keeps working until the next API call fails with invalid_grant or token_expired. Handle it gracefully: catch the error, clear tokens, redirect to login.
Why refresh tokens expire
- Inactivity timeout โ providers expire refresh tokens after a period of no use (Auth0 default: 30 days, Cognito: 30 days, Google: 6 months)
- Token rotation โ each refresh produces a new refresh token and invalidates the old one. Using an old token causes invalid_grant
- User revoked access โ the user disconnected your app via provider settings
- Password changed โ some providers revoke all tokens when a password changes
Catch expiry in your token refresh logic
async function getValidToken() { const stored = getStoredTokens(); if (!stored) return promptLogin(); // Check if access token is still valid if (Date.now() < stored.expires_at - 60000) { return stored.access_token; } // Try to refresh try { const fresh = await refreshAccessToken(stored.refresh_token); storeTokens(fresh); return fresh.access_token; } catch (err) { if (err.error === 'invalid_grant' || err.status === 401) { clearTokens(); promptLogin(); // redirect to /login return null; } throw err; // re-throw other errors }
}
Token lifetimes by provider
| Provider | Access token | Refresh token | Idle expiry |
|---|---|---|---|
| Auth0 | 24h (configurable) | No expiry by default | 30 days idle |
| AWS Cognito | 1h | 30 days | 30 days from issue |
| 1h | No expiry | 6 months unused | |
| Microsoft/Azure | 1h | 90 days | 90 days idle |
| Okta | 1h | Configurable | Configurable |
Silent re-authentication for SPAs
If you want to avoid visible login prompts, use silent auth โ an invisible iframe that attempts to get a new token using a session cookie:
// Auth0 example โ checkSession
auth0.checkSession({}, function(err, result) { if (err) { // Session expired โ full login required auth0.authorize(); } else { // New tokens in result updateTokens(result); }
}); Debug your OAuth error live โ OAuthFixer