Discord error 50025: Invalid OAuth2 access token provided
Last verified against Discord Developer Docs - Opcodes and status codes
Invalid OAuth2 access token providedWhat error 50025 means
You sent Authorization: Bearer <token> and the token is not a valid, current OAuth2 access token for your application. Access tokens expire (the token response includes expires_in, commonly seven days), they are revoked when the user removes your app from Authorized Apps, and they are tied to the application that issued them. Any of those conditions yields 50025.
This is the OAuth2 sibling of 50014. It shows up in "login with Discord" backends and linked-roles flows that store a token and use it days later: the token has expired and the code never refreshed it. It also appears when a bot token is sent with the Bearer prefix, or a bearer token is sent to a route that only accepts Bot auth.
What it looks like
{
"message": "Invalid OAuth2 access token provided",
"code": 50025
}Why it happens
- Access token expired and was not refreshed using the refresh_token
- User revoked the authorization in their Discord settings
- Token issued by a different application (different client_id)
- Bot token used with the Bearer prefix, or bearer token used where Bot auth is required
- Token stored truncated or with surrounding whitespace
How to fix Discord error 50025
- 1Exchange the stored refresh_token at POST /oauth2/token with grant_type=refresh_token and use the new access token
- 2If refresh fails with invalid_grant, the user must re-authorize; send them back through the OAuth2 flow
- 3Check GET /oauth2/@me with the token to see its scopes, expiry and application
- 4Use Bot auth for bot routes and Bearer only for user-scoped routes
- 5Verify client_id and client_secret match the application that issued the token
How to stop it recurring
Store expires_at alongside every access token and refresh proactively before use when it is within a few minutes of expiry. Treat revocation as a normal path in your UI ("reconnect your Discord account"), and never persist tokens across application IDs.
OAuth2 token lifecycles belong in your data model, not in your error handler: store access token, refresh token, expiry and scopes as one record. The refresh flow that keeps this error away is the same one that prevents 50026 surprises after scope changes; if the failing credential is the bot token instead, you are looking at 50014.
Official reference: Discord Developer Docs - Opcodes and status codes. See all Discord error codes or the Discord limits and quotas.
Related codes
- 50026: Missing required OAuth2 scopeMissing required OAuth2 scope
- 50014: Invalid authentication token providedInvalid authentication token provided
- 40001: UnauthorizedUnauthorized. Provide a valid token and try again
- 20012: Not authorized to perform this action on this applicationYou are not authorized to perform this action on this application
Error 50025 - quick answers
What does Discord error 50025 mean?
You sent Authorization: Bearer <token> and the token is not a valid, current OAuth2 access token for your application. Access tokens expire (the token response includes expires_in , commonly seven days), they are revoked when the user removes your app from Authorized Apps, and they are tied to the application that issued them. Any of those conditions yields 50025. This is the OAuth2 sibling of 50014 .
How do I fix Discord error 50025?
1. Exchange the stored refresh_token at POST /oauth2/token with grant_type=refresh_token and use the new access token 2. If refresh fails with invalid_grant, the user must re-authorize; send them back through the OAuth2 flow 3. Check GET /oauth2/@me with the token to see its scopes, expiry and application 4. Use Bot auth for bot routes and Bearer only for user-scoped routes 5. Verify client_id and client_secret match the application that issued the token
Stop debugging Discord by hand
Connect the channel through Conferbot: tokens, webhooks and retries are handled, failures show as readable status.