Discord API reference

Discord API error codes, explained one by one

73documented codes
9categories
2026-08-20last verified

Last verified against Discord Developer Docs - Opcodes and status codes

Discord surfaces errors in three different places, and the first job when debugging a bot is working out which one you are looking at. REST errors come back as an HTTP status (400, 401, 403, 404, 429) plus a JSON body containing a numeric code and a human-readable message. The HTTP status tells you the class of failure; the code tells you the specific reason. Code 50013 and code 50001 both arrive as HTTP 403, but they need different fixes.

Gateway close codes (4000-4014) are not HTTP at all. They are WebSocket close frames sent when Discord drops your bot's persistent connection. You will see them in your library's disconnect or shardDisconnect event, never in a REST response. A bot that shows offline is almost always dealing with one of these, most often 4004 (bad token) or 4014 (privileged intent not enabled in the Developer Portal).

HTTP 429 is a rate limit. Its body has no Discord error code unless a specific resource limit was hit; instead it carries retry_after and a global flag, and the response headers (X-RateLimit-Bucket, X-RateLimit-Scope) tell you which bucket you exhausted.

Validation failures (50035) add a nested errors object that names the exact field that was rejected. Most libraries print this object when you log the error; if yours does not, log the raw response body. Each entry below quotes the literal message Discord returns, lists the causes we see most, and gives steps you can test one at a time. For the bigger picture on a bot that is online but silent, read Discord bot not responding.

How to read a Discord error

// Simple REST error (HTTP 403)
{
  "message": "Missing Permissions",
  "code": 50013
}

// Validation error (HTTP 400) - note the nested "errors" object
{
  "code": 50035,
  "errors": {
    "embeds": {
      "0": {
        "description": {
          "_errors": [
            {
              "code": "BASE_TYPE_MAX_LENGTH",
              "message": "Must be 4096 or fewer in length."
            }
          ]
        }
      }
    }
  },
  "message": "Invalid Form Body"
}

// Rate limit (HTTP 429) - no Discord code, uses retry_after + global
{
  "message": "You are being rate limited.",
  "retry_after": 64.57,
  "global": false
}

// Deferred initial interaction response (send within 3 seconds to avoid 10062)
// POST /interactions/{interaction.id}/{interaction.token}/callback
{ "type": 5 }

// Gateway close frame (WebSocket, not HTTP)
// close code: 4014, reason: "Disallowed intent(s)."

All 73 codes

Jump to: Unknown resource (10xxx) (7) · Permissions and access (7) · Maximum reached (30xxx) (11) · Rate limits and slowmode (6) · Interactions and slash commands (3) · Validation and request shape (17) · Tokens and OAuth2 (5) · AutoMod and content filters (3) · Gateway close codes (4000-4014) (14)

Unknown resource (10xxx)

CodeTitleHTTPType
10003Unknown channel
Unknown channel
404Permanent - do not retry
10004Unknown guild
Unknown guild
404Permanent - do not retry
10007Unknown member
Unknown member
404Permanent - do not retry
10008Unknown message
Unknown message
404Permanent - do not retry
10013Unknown user
Unknown user
404Permanent - do not retry
10014Unknown emoji
Unknown emoji
404Permanent - do not retry
10015Unknown webhook
Unknown webhook
404Permanent - do not retry

Permissions and access

CodeTitleHTTPType
20012Not authorized to perform this action on this application
You are not authorized to perform this action on this application
403Configuration
40007User is banned from this guild
The user is banned from this guild
403Permanent - do not retry
50001Missing access
Missing access
403Configuration
50005Cannot edit a message authored by another user
Cannot edit a message authored by another user
403Permanent - do not retry
50007Cannot send messages to this user
Cannot send messages to this user
403Permanent - do not retry
50013Missing permissions
You lack permissions to perform that action
403Configuration
160002Cannot reply without permission to read message history
Cannot reply without permission to read message history
403Configuration

Maximum reached (30xxx)

CodeTitleHTTPType
30001Maximum number of guilds reached (100)
Maximum number of guilds reached (100)
400Configuration
30003Maximum number of pins reached for the channel (250)
Maximum number of pins reached for the channel (250)
400Permanent - do not retry
30005Maximum number of guild roles reached (250)
Maximum number of guild roles reached (250)
400Permanent - do not retry
30007Maximum number of webhooks reached (15)
Maximum number of webhooks reached (15)
400Permanent - do not retry
30010Maximum number of reactions reached (20)
Maximum number of reactions reached (20)
400Permanent - do not retry
30013Maximum number of guild channels reached (500)
Maximum number of guild channels reached (500)
400Permanent - do not retry
30016Maximum number of invites reached (1000)
Maximum number of invites reached (1000)
400Permanent - do not retry
30030Maximum number of server categories reached (5)
Maximum number of server categories has been reached (5)
400Permanent - do not retry
30034Maximum number of daily application command creates reached (200)
Maximum number of daily application command creates has been reached (200)
400Retryable
30046Maximum edits to messages older than 1 hour reached
Maximum number of edits to messages older than 1 hour reached. Try again later
400Retryable
50045File uploaded exceeds the maximum size
File uploaded exceeds the maximum size
400Permanent - do not retry

Rate limits and slowmode

CodeTitleHTTPType
20016Slowmode rate limit
This action cannot be performed due to slowmode rate limit
429Retryable
20022Announcement rate limit on message edit
This message cannot be edited due to announcement rate limits
429Retryable
20028Channel write rate limit
The write action you are performing on the channel has hit the write rate limit
429Retryable
20029Server write rate limit
The write action you are performing on the server has hit the write rate limit
429Retryable
40003Opening direct messages too fast
You are opening direct messages too fast
429Retryable
429HTTP 429 Too Many Requests (rate limited)
You are being rate limited.
429Retryable

Interactions and slash commands

CodeTitleHTTPType
10062Unknown interaction
Unknown interaction
404Permanent - do not retry
10063Unknown application command
Unknown application command
404Permanent - do not retry
40060Interaction has already been acknowledged
Interaction has already been acknowledged
400Permanent - do not retry

Validation and request shape

CodeTitleHTTPType
0General error
General error (such as a malformed request body, amongst other things)
400Permanent - do not retry
40005Request entity too large
Request entity too large. Try sending something smaller in size
413Permanent - do not retry
40032Target user is not connected to voice
Target user is not connected to voice
400Permanent - do not retry
40061Tag names must be unique
Tag names must be unique
400Permanent - do not retry
50003Cannot execute action on a DM channel
Cannot execute action on a DM channel
400Permanent - do not retry
50006Cannot send an empty message
Cannot send an empty message
400Permanent - do not retry
50008Cannot send messages in a non-text channel
Cannot send messages in a non-text channel
400Permanent - do not retry
50019Message can only be pinned to its own channel
A message can only be pinned to the channel it was sent in
400Permanent - do not retry
50021Cannot execute action on a system message
Cannot execute action on a system message
400Permanent - do not retry
50024Cannot execute action on this channel type
Cannot execute action on this channel type
400Permanent - do not retry
50033Invalid recipient(s)
Invalid Recipient(s)
400Permanent - do not retry
50034Message too old to bulk delete
A message provided was too old to bulk delete
400Permanent - do not retry
50035Invalid form body
Invalid form body (returned for both application/json and multipart/form-data bodies), or invalid Content-Type provided
400Permanent - do not retry
50041Invalid API version provided
Invalid API version provided
400Configuration
50046Invalid file uploaded
Invalid file uploaded
400Permanent - do not retry
50109Request body contains invalid JSON
The request body contains invalid JSON.
400Permanent - do not retry
220003Webhooks can only create threads in forum channels
Webhooks can only create threads in forum channels
400Permanent - do not retry

Tokens and OAuth2

CodeTitleHTTPType
40001Unauthorized
Unauthorized. Provide a valid token and try again
401Configuration
40002Account verification required
You need to verify your account in order to perform this action
403Configuration
50014Invalid authentication token provided
Invalid authentication token provided
401Configuration
50025Invalid OAuth2 access token provided
Invalid OAuth2 access token provided
401Configuration
50026Missing required OAuth2 scope
Missing required OAuth2 scope
403Configuration

AutoMod and content filters

CodeTitleHTTPType
200000Message was blocked by automatic moderation
Message was blocked by automatic moderation
400Policy / account
200001Title was blocked by automatic moderation
Title was blocked by automatic moderation
400Policy / account
240000Message blocked by harmful links filter
Message blocked by harmful links filter
400Policy / account

Gateway close codes (4000-4014)

CodeTitleHTTPType
4000Unknown error
We're not sure what went wrong. Try reconnecting?
Retryable
4001Unknown opcode
You sent an invalid Gateway opcode or an invalid payload for an opcode. Don't do that!
Permanent - do not retry
4002Decode error
You sent an invalid payload to Discord. Don't do that!
Permanent - do not retry
4003Not authenticated
You sent us a payload prior to identifying, or this session has been invalidated.
Retryable
4004Authentication failed
The account token sent with your identify payload is incorrect.
Configuration
4005Already authenticated
You sent more than one identify payload. Don't do that!
Permanent - do not retry
4007Invalid seq
The sequence sent when resuming the session was invalid. Reconnect and start a new session.
Retryable
4008Rate limited
Woah nelly! You're sending payloads to us too quickly. Slow it down! You will be disconnected on receiving this.
Retryable
4009Session timed out
Your session timed out. Reconnect and start a new one.
Retryable
4010Invalid shard
You sent us an invalid shard when identifying.
Configuration
4011Sharding required
The session would have handled too many guilds - you are required to shard your connection in order to connect.
Configuration
4012Invalid API version
You sent an invalid version for the gateway.
Configuration
4013Invalid intent(s)
You sent an invalid intent for a Gateway Intent. You may have incorrectly calculated the bitwise value.
Configuration
4014Disallowed intent(s)
You sent a disallowed intent for a Gateway Intent. You may have tried to specify an intent that you have not enabled …
Configuration

Discord guides and tools

Other platforms

Frequently asked questions

Where do I find the Discord error code in a failed request?

In the JSON response body, not the HTTP status line. Every REST error from Discord contains a numeric code field and a message field, for example {"message": "Missing Permissions", "code": 50013}. Validation errors (50035) add an errors object that drills down to the field that was rejected. Most libraries expose this as error.code (discord.js: DiscordAPIError, discord.py: discord.HTTPException with .code). If your library swallows the body, log the raw response before giving up.

What is the difference between Discord error 50001 and 50013?

50001 Missing Access means the bot cannot see the resource at all: it is not in the guild, the channel is hidden from it by a permission overwrite, or the token lacks the OAuth2 scope. 50013 Missing Permissions means the bot can see the resource but lacks the specific permission bit for that action (Send Messages, Manage Roles, Kick Members and so on). Fix 50001 by granting View Channel or re-inviting; fix 50013 by granting the specific permission and checking role hierarchy.

Why does my Discord bot get 10062 Unknown interaction?

The interaction expired before you acknowledged it. Discord gives you 3 seconds from the time the interaction is created to send an initial response. If your handler takes longer (a database call, an external API, a cold start) the token is discarded and any reply returns 10062. The fix is to defer immediately (response type 5, DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE) and then edit the deferred reply within the 15-minute follow-up window.

What does Discord gateway close code 4014 mean?

Disallowed intent(s). Your IDENTIFY payload asked for a privileged intent (Server Members, Presence or Message Content) that is not switched on in the Developer Portal under Bot > Privileged Gateway Intents. Discord refuses the connection and your bot appears offline. Enable the toggle, or remove the intent from your code. Do not reconnect in a loop while this is unresolved; 4014 is marked as not reconnectable.

Are Discord gateway close codes the same as HTTP error codes?

No. Close codes 4000-4014 are WebSocket close frames on the persistent gateway connection that delivers events to your bot. They never appear in REST responses and have no JSON body; you will see them in your library's disconnect handler. HTTP errors (400, 401, 403, 404, 429) come from REST calls such as sending a message, and carry a JSON body with a code and message.

How do I handle Discord HTTP 429 rate limits correctly?

Read retry_after from the JSON body (seconds, as a float) and wait at least that long before retrying the same route. Check the global field: if true, pause every request from the bot, not just that route. Use the X-RateLimit-Bucket header to group routes that share a limit, and X-RateLimit-Remaining to stop before you hit zero. Repeated 401, 403 and 429 responses count against the 10,000-per-10-minutes invalid request limit that leads to a temporary Cloudflare ban.

Why does a Discord message send fail with 50035 Invalid Form Body?

A field in your request violated a validation rule: an embed description over 4,096 characters, a content string over 2,000, more than 25 embed fields, a custom_id over 100 characters, an invalid snowflake, a wrong Content-Type, and so on. The response body contains an errors object whose nested keys name the exact field (for example embeds.0.description._errors). Log that object; it almost always tells you precisely what to change.

Which Discord errors are safe to retry automatically?

HTTP 429 (after retry_after), 502 and other 5xx, and gateway close codes marked reconnectable (4000, 4001, 4002, 4003, 4005, 4007, 4008, 4009). Do not auto-retry 40001, 50014 or gateway 4004 (bad token), 4010-4014 (sharding, API version, intents), 50013 and 50001 (permissions), or any 10xxx unknown-resource error. Retrying those produces identical failures and pushes you toward the invalid request ban.

How do I fix Discord error 40060 Interaction has already been acknowledged?

You sent two initial responses to one interaction. After deferReply() in discord.js you must use editReply() or followUp(), never reply() again; in discord.py, after interaction.response.defer() use interaction.edit_original_response() or interaction.followup.send(). Also check for two processes running with the same token, both answering the same interaction. Each interaction accepts exactly one callback; everything after it goes through the webhook routes.

What happens if my bot keeps sending invalid requests to Discord?

Requests that return 401, 403 or 429 count as invalid requests. An IP that produces 10,000 of them within 10 minutes is temporarily restricted from the API by Cloudflare, so every call returns an HTML error page instead of JSON until the ban expires. Retry loops around a bad token, a missing permission, or an unhandled 429 are the usual cause. Fix the underlying error instead of retrying it.

Run your Discord bot without babysitting error codes

Conferbot manages the connection, tokens, webhooks and retries, and shows failures as readable status.