Slack API reference

Slack API errors, explained one by one

40documented codes
7categories
2026-08-20last verified

Last verified against Slack API reference - chat.postMessage errors

Slack does not use numeric error codes. A failed Web API call returns HTTP 200 with a JSON body whose ok field is false and whose error field carries a short machine-readable string: channel_not_found, missing_scope, invalid_auth. That HTTP 200 is the defining trap. Monitoring that alerts on non-2xx status codes reports a perfectly healthy integration while every single message silently fails, because the only Slack error that reliably changes the status line is rate limiting, which returns HTTP 429 with a Retry-After header. If you check nothing else, check ok on every response.

Slack errors surface in three distinct places, and the debugging path is different for each. First, the Web API: every method you call (chat.postMessage, conversations.open, views.open) answers with the ok/error envelope described above, and each method's reference page lists the strings it can return. Second, the Events API: here Slack calls you, so failures show up as missing events, X-Slack-Retry-Num headers on duplicate deliveries, or an app_rate_limited event when you exceed 30,000 deliveries an hour — nothing appears in your request logs because you never made a request. Third, request signature verification: if your endpoint rejects Slack's X-Slack-Signature header (or fails the initial url_verification challenge), Slack marks your Request URL as broken and stops delivering entirely.

Every string on this page appears in Slack's own reference documentation, and each entry links to the method page that documents it. The entries are grouped by what actually went wrong — authentication, scopes, channel membership, message content, rate limits, event delivery, or Slack's side. For the ceilings that produce several of these errors, see Slack API limits; for a symptom-first walkthrough of a bot that has gone quiet, see Slack bot not responding.

How to read a Slack error

The Web API documentation states that every response "will always contain a top-level boolean property ok that indicates success or failure." On failure, "the error property will contain a short machine-readable error code." Some errors add sibling fields that name the problem precisely — missing_scope returns needed and provided — and Block Kit validation failures often attach a response_metadata object whose messages array points at the failing block. Log the entire body, not just error. The shapes to recognize:

HTTP 200
{"ok": false, "error": "too_many_attachments"}

HTTP 200
{
  "ok": false,
  "error": "missing_scope",
  "needed": "chat:write",
  "provided": "channels:read,users:read"
}

HTTP 200 (partial success: ok stays true, read the warning)
{"ok": true, "warning": "something_problematic", "ts": "1503435956.000247"}

HTTP 200 (block validation; messages array locates the failure)
{
  "ok": false,
  "error": "invalid_blocks",
  "response_metadata": { "messages": [ "...pointer to the failing block..." ] }
}

HTTP 429 (the one status-line error)
Retry-After: 30
{"ok": false, "error": "ratelimited"}

All 40 codes

Jump to: Tokens & authentication (6) · Scopes, permissions & admin policy (7) · Channels, membership & DMs (6) · Message content & Block Kit (12) · Rate limiting (3) · Events API & webhooks (2) · Slack-side errors (4)

Tokens & authentication

CodeTitleHTTPType
not_authedNo authentication token provided
No authentication token provided.
200Configuration
invalid_authAuthentication cannot be validated
Some aspect of authentication cannot be validated. Either the provided token is invalid or the request originates fro…
200Configuration
account_inactiveToken for a deleted user or workspace
Authentication token is for a deleted user or workspace when using a bot token.
200Permanent - do not retry
token_revokedToken has been revoked
Authentication token is for a deleted user or workspace or the app has been removed when using a user token.
200Permanent - do not retry
token_expiredToken has expired
Authentication token has expired
200Configuration
two_factor_setup_requiredTwo-factor setup is required
Two factor setup is required.
200Policy / account

Scopes, permissions & admin policy

CodeTitleHTTPType
missing_scopeToken lacks a required OAuth scope
The token used is not granted the specific scope permissions required to complete this request.
200Configuration
no_permissionToken lacks permission in this context
The workspace token used in this request does not have the permissions necessary to complete the request. Make sure y…
200Configuration
not_allowed_token_typeWrong class of token for this method
The token type used in this request is not allowed.
200Configuration
restricted_actionA workspace preference blocks this posting
A workspace preference prevents the authenticated user from posting.
200Policy / account
ekm_access_deniedAdmins have disabled messaging here (EKM)
Administrators have suspended the ability to post a message.
200Policy / account
team_access_not_grantedToken not granted access to this workspace
The token used is not granted the specific workspace access required to complete this request.
200Configuration
as_user_not_supportedas_user is not supported here
The as_user parameter does not function with workspace apps.
200Permanent - do not retry

Channels, membership & DMs

CodeTitleHTTPType
channel_not_foundValue passed for channel was invalid
Value passed for channel was invalid.
200Permanent - do not retry
not_in_channelBot is not a member of the channel
Cannot post user messages to a channel they are not in.
200Configuration
is_archivedChannel has been archived
Channel has been archived.
200Permanent - do not retry
method_not_supported_for_channel_typeThis conversation type can't be used here
This type of conversation cannot be used with this method.
200Permanent - do not retry
user_not_foundValue(s) passed for users was invalid
Value(s) passed for users was invalid.
200Permanent - do not retry
messages_tab_disabledThe app's Messages tab is disabled
Messages tab for the app is disabled.
200Configuration

Message content & Block Kit

CodeTitleHTTPType
msg_too_longMessage text is too long
Message text is too long.
200Permanent - do not retry
no_textNo message text provided
No message text provided.
200Permanent - do not retry
invalid_blocksBlocks are not valid
Blocks submitted with this message are not valid.
200Permanent - do not retry
invalid_blocks_formatblocks is not a valid JSON array
The blocks is not a valid JSON object or doesn't match the Block Kit syntax.
200Permanent - do not retry
invalid_argumentsMethod called with invalid arguments
The method was called with invalid arguments.
200Permanent - do not retry
too_many_attachmentsMore than 100 attachments on a message
Too many attachments were provided with this message. A maximum of 100 attachments are allowed on a message.
200Permanent - do not retry
duplicate_channel_not_foundclient_msg_id points at an invalid channel
Channel associated with client_msg_id was invalid.
200Permanent - do not retry
duplicate_message_not_foundNo duplicate message for this client_msg_id
No duplicate message exists associated with client_msg_id.
200Permanent - do not retry
message_not_foundNo message at that timestamp
No message exists with the requested timestamp.
200Permanent - do not retry
cant_update_messageNot allowed to update this message
Authenticated user does not have permission to update this message.
200Policy / account
cant_delete_messageNot allowed to delete this message
Authenticated user does not have permission to delete this message.
200Policy / account
edit_window_closedThe edit window has closed
The message cannot be edited due to the team message edit settings
200Policy / account

Rate limiting

CodeTitleHTTPType
ratelimitedRequest was rate limited (HTTP 429)
The request has been ratelimited. Refer to the Retry-After header for when to retry the request.
429Retryable
rate_limitedPosting messages too quickly
Application has posted too many messages, read the Rate Limit documentation for more information.
429Retryable
message_limit_exceededWorkspace message usage limit reached
Members on this team are sending too many messages. For more details, see https://slack.com/help/articles/11500242294…
200Policy / account

Events API & webhooks

CodeTitleHTTPType
app_rate_limitedEvents API deliveries rate limited
"type": "app_rate_limited"
Retryable
url_verificationRequest URL fails verification / events stop
{"type": "url_verification", "challenge": "..."}
Configuration

Slack-side errors

CodeTitleHTTPType
fatal_errorCatastrophic error on Slack's side
The server could not complete your operation(s) without encountering a catastrophic error. It's possible some aspect …
200Retryable
internal_errorTransient error on Slack's side
The server could not complete your operation(s) without encountering an error, likely due to a transient issue on our…
200Retryable
service_unavailableService temporarily unavailable
The service is temporarily unavailable
200Retryable
request_timeoutPOST data missing or truncated
The method was called via a POST request, but the POST data was either missing or truncated.
200Configuration

Slack guides and tools

Other platforms

Frequently asked questions

Why does Slack return HTTP 200 when my API call failed?

The Web API signals failure in the body, not the status line: every response carries a boolean ok, and when it is false the error field holds a machine-readable string like channel_not_found. Only rate limiting changes the status code, to 429 with a Retry-After header. Any error handling built on HTTP status alone will treat every Slack failure as success.

What is the difference between channel_not_found and not_in_channel?

channel_not_found means the channel value did not resolve — usually a #name passed where a C-prefixed ID is required, or a private channel the bot cannot see. not_in_channel means the channel resolved but the bot is not a member. The fix for the first is the right ID; the fix for the second is /invite or the chat:write.public scope for public channels.

How do I fix missing_scope?

The response tells you: needed names the scope the method requires and provided lists what your token has. Add the needed scope under OAuth & Permissions, then reinstall the app to the workspace — scopes only take effect on the token issued at install, so editing the scope list without reinstalling changes nothing.

Why did my Slack bot stop working after the app was reinstalled?

Reinstalling or removing an app revokes previously issued tokens, and old tokens then return token_revoked (or invalid_auth). Tokens are also revoked when the installing user is deactivated on user-token installs. Always store the token issued by the most recent oauth.v2.access exchange and treat token_revoked as a signal to re-run the install flow.

What is the difference between ratelimited, rate_limited and app_rate_limited?

ratelimited is the generic Web API answer, sent with HTTP 429 and a Retry-After header stating how many seconds to wait. rate_limited is documented on chat.postMessage for apps posting messages too quickly. app_rate_limited is an Events API event delivered when an app exceeds 30,000 event deliveries per workspace per hour — it arrives as an event, not as an API response.

What causes invalid_auth?

Slack documents it as authentication that cannot be validated: the token is invalid — truncated, from another workspace, an app-level xapp- token used on a Web API method — or the request comes from an IP address the app or admin has disallowed. Check the token with auth.test first; if that passes, look at IP allowlists.

Why can't my app DM a user (messages_tab_disabled)?

The app's Messages tab is switched off in its configuration, so Slack refuses bot DMs with messages_tab_disabled. Open the app's settings under App Home, enable the Messages Tab, and if you want users to write to the bot also tick 'Allow users to send Slash commands and messages from the messages tab'. No scope fixes this — it is an app configuration toggle.

What is response_metadata.messages in a Slack error response?

On several validation failures — Block Kit problems in particular — Slack attaches a response_metadata object whose messages array contains human-readable strings pointing at the specific block or field that failed. It is the fastest way to locate an invalid_blocks failure in a 40-block payload, but only exists if you log the full response body rather than just the error field.

Do the official Slack SDKs throw exceptions for ok:false responses?

Yes. Node's @slack/web-api rejects the promise with an error whose code is ErrorCode.PlatformError and whose data property holds Slack's response body; rate-limited calls are retried automatically unless rejectRateLimitedCalls is true. Python's slack_sdk raises slack_sdk.errors.SlackApiError, with the string in e.response["error"] and Retry-After available via e.response.headers.

Why do my Slack events arrive two or three times?

Slack requires an HTTP 2xx acknowledgment within 3 seconds of delivering an event. Miss it and Slack retries up to three times — almost immediately, after 1 minute, then after 5 minutes — marking each retry with X-Slack-Retry-Num and X-Slack-Retry-Reason headers. Acknowledge first and process asynchronously, and deduplicate on event_id.

Run your Slack bot without babysitting error codes

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