Slack OAuth refresh token invalid_grant — What it means & how to fix it
How to diagnose and fix Slack refresh token invalid_grant errors
"error": "invalid_grant", "error_description": "Token has been expired or revoked."
If you integrate with Slack using OAuth 2.0, refresh failures usually show up during token rotation. When that refresh breaks, syncs stall and user-triggered actions fail until the connection is re-authorized.
Below is a Slack-specific breakdown of what invalid_grant usually means, what triggers it, and how to avoid repeat incidents. For broader context, see API Auth Is Deeper Than It Looks and Why OAuth Is Still Hard.
Spot the error
When your backend POSTs to https://slack.com/api/oauth.v2.access with grant_type=refresh_token to swap a refresh token for a new access token, Slack can answer with HTTP error code 400:
Slack OAuth refresh error
{
"error": "invalid_grant",
"error_description": "Token has been expired or revoked."
}
That single JSON payload means the refresh token is unusable. Retrying the same request will keep failing until the underlying cause is fixed.
Why was the refresh token revoked?
Slack refresh tokens exist only when token rotation is enabled. That opt-in design creates failure modes that aren’t typical for providers that always issue refresh tokens.
1) Token rotation not enabled (no refresh token)
If token rotation is off, Slack never issues refresh tokens. Any refresh attempt fails because there’s no valid refresh token to redeem.
2) You used a stale refresh token
Slack rotates refresh tokens. Each successful refresh returns a new refresh token and revokes the previous one. If you keep the old token (or overwrite the new one in a race), the next refresh fails.
3) Access token expired before refresh
With rotation enabled, access tokens are short-lived. You must refresh beforeexpires_in elapses. If you miss the window, both access and refresh tokens can become unusable and re-auth is required.
4) App uninstalled or access revoked
If a user removes your app or an admin revokes access, Slack invalidates the tokens tied to that installation immediately.
5) Client credentials mismatch
Using the wrong client_id or client_secret makes a valid refresh token appear invalid.
How to fix it
1. Confirm token rotation is enabled
No rotation means no refresh token. Re-authorize with rotation enabled to start receiving refresh tokens.
2. Ensure you store the latest refresh token
Persist the new refresh_token immediately after each refresh and use it for the next refresh.
3. Refresh before expires_in
Schedule refresh jobs ahead of expiry, not after.
4. If it’s truly invalid/revoked: re-auth
Once a refresh token is invalid, the only fix is to send the user through OAuth again.
If you need guidance on handling retries and concurrency, see How to handle concurrency with OAuth token refreshes.
How to prevent refresh token issues
A few engineering habits go a long way:
- Enable token rotation intentionally
Refresh tokens are opt-in in Slack. - Persist the rotated refresh token
Always store the newest refresh token returned by Slack. - Make refresh single-flight
Avoid overwriting token state when multiple workers refresh. - Refresh ahead of
expires_in
Schedule refresh before the deadline. - Build a re-auth flow
Have a clear “Reconnect Slack” UX for revoked installations.
Skip the headache, let Nango refresh for you
Nango is an open-source auth layer that handles OAuth token lifecycles in production:
- Secure storage for access + refresh tokens
- Automatic access-token refresh
- Concurrency-safe refresh logic
- Clear signals when a connection needs re-auth
If you’re building a Slack API integration and tired of token lifecycle edge cases, Nango can manage the refresh pipeline so you can focus on product.




