Discord API · error code

Discord error 50026: Missing required OAuth2 scope

ConfigurationHTTP 403Tokens and OAuth2

Last verified against Discord Developer Docs - Opcodes and status codes

What Discord returns
Missing required OAuth2 scope

What error 50026 means

The bearer token is valid, but it was granted without the scope the endpoint needs. OAuth2 scopes are fixed at authorization time: if the user consented to identify only, a later call to GET /users/@me/guilds (which needs guilds) or to PUT /guilds/{id}/members/{user} (guilds.join) returns 50026. The token does not automatically gain scopes because your application has since started asking for them.

This error is unrelated to server permissions. It is entirely about what the user agreed to on the consent screen. The fix is always to re-run the authorization with the correct scope list, then use the new token.

Common scope pairs to check: identify vs email, guilds vs guilds.members.read (needed to read the user's member object in a specific guild), connections for linked accounts, role_connections.write for linked roles, and applications.commands when installing commands without a bot user.

What it looks like

{
  "message": "Missing required OAuth2 scope",
  "code": 50026
}

Why it happens

  • Authorization URL missing the scope (for example scope=identify without guilds)
  • Tokens issued before you added a new scope to your app's flow
  • Calling a guild-member endpoint with a token that has guilds but not guilds.members.read
  • guilds.join called with a user token lacking that scope, or with a bot lacking Create Instant Invite
  • Scope string malformed (comma-separated instead of space-separated, or URL-encoding issues)

How to fix Discord error 50026

  1. 1Check the token's scopes at GET /oauth2/@me and compare to what the route requires
  2. 2Update the authorization URL to include the required scopes (space-separated, URL-encoded as %20)
  3. 3Force re-authorization for affected users (prompt=consent) and replace their stored tokens
  4. 4For guilds.join, ensure the user token has guilds.join and the bot has Create Instant Invite in the guild
  5. 5Store granted scopes next to each token so you can detect missing ones before calling

How to stop it recurring

Request every scope your product will need in the first consent, and version your token records with the scope list they were granted. When you introduce a feature that needs a new scope, gate it on that record and prompt re-authorization only for users who lack it.

Scopes are consent, and consent does not upgrade itself; every scope addition is a migration across your user base. Track granted scopes per token, gate features on them, and re-consent lazily. The related credential failures triage cleanly: 50025 for an expired or revoked token, 50001 when the scope exists but guild-side access does not.

Official reference: Discord Developer Docs - Opcodes and status codes. See all Discord error codes or the Discord limits and quotas.

Related codes

Error 50026 - quick answers

What does Discord error 50026 mean?

The bearer token is valid, but it was granted without the scope the endpoint needs. OAuth2 scopes are fixed at authorization time: if the user consented to identify only, a later call to GET /users/@me/guilds (which needs guilds ) or to PUT /guilds/{id}/members/{user} ( guilds.join ) returns 50026. The token does not automatically gain scopes because your application has since started asking for them.

How do I fix Discord error 50026?

1. Check the token's scopes at GET /oauth2/@me and compare to what the route requires 2. Update the authorization URL to include the required scopes (space-separated, URL-encoded as %20) 3. Force re-authorization for affected users (prompt=consent) and replace their stored tokens 4. For guilds.join, ensure the user token has guilds.join and the bot has Create Instant Invite in the guild 5. Store granted scopes next to each token so you can detect missing ones before calling

Stop debugging Discord by hand

Connect the channel through Conferbot: tokens, webhooks and retries are handled, failures show as readable status.