Slack API errors, explained one by one
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
| Code | Title |
|---|---|
not_authed | No authentication token provided No authentication token provided. |
invalid_auth | Authentication cannot be validated Some aspect of authentication cannot be validated. Either the provided token is invalid or the request originates fro… |
account_inactive | Token for a deleted user or workspace Authentication token is for a deleted user or workspace when using a bot token. |
token_revoked | Token has been revoked Authentication token is for a deleted user or workspace or the app has been removed when using a user token. |
token_expired | Token has expired Authentication token has expired |
two_factor_setup_required | Two-factor setup is required Two factor setup is required. |
Scopes, permissions & admin policy
| Code | Title |
|---|---|
missing_scope | Token lacks a required OAuth scope The token used is not granted the specific scope permissions required to complete this request. |
no_permission | Token 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… |
not_allowed_token_type | Wrong class of token for this method The token type used in this request is not allowed. |
restricted_action | A workspace preference blocks this posting A workspace preference prevents the authenticated user from posting. |
ekm_access_denied | Admins have disabled messaging here (EKM) Administrators have suspended the ability to post a message. |
team_access_not_granted | Token not granted access to this workspace The token used is not granted the specific workspace access required to complete this request. |
as_user_not_supported | as_user is not supported here The as_user parameter does not function with workspace apps. |
Channels, membership & DMs
| Code | Title |
|---|---|
channel_not_found | Value passed for channel was invalid Value passed for channel was invalid. |
not_in_channel | Bot is not a member of the channel Cannot post user messages to a channel they are not in. |
is_archived | Channel has been archived Channel has been archived. |
method_not_supported_for_channel_type | This conversation type can't be used here This type of conversation cannot be used with this method. |
user_not_found | Value(s) passed for users was invalid Value(s) passed for users was invalid. |
messages_tab_disabled | The app's Messages tab is disabled Messages tab for the app is disabled. |
Message content & Block Kit
| Code | Title |
|---|---|
msg_too_long | Message text is too long Message text is too long. |
no_text | No message text provided No message text provided. |
invalid_blocks | Blocks are not valid Blocks submitted with this message are not valid. |
invalid_blocks_format | blocks is not a valid JSON array The blocks is not a valid JSON object or doesn't match the Block Kit syntax. |
invalid_arguments | Method called with invalid arguments The method was called with invalid arguments. |
too_many_attachments | More than 100 attachments on a message Too many attachments were provided with this message. A maximum of 100 attachments are allowed on a message. |
duplicate_channel_not_found | client_msg_id points at an invalid channel Channel associated with client_msg_id was invalid. |
duplicate_message_not_found | No duplicate message for this client_msg_id No duplicate message exists associated with client_msg_id. |
message_not_found | No message at that timestamp No message exists with the requested timestamp. |
cant_update_message | Not allowed to update this message Authenticated user does not have permission to update this message. |
cant_delete_message | Not allowed to delete this message Authenticated user does not have permission to delete this message. |
edit_window_closed | The edit window has closed The message cannot be edited due to the team message edit settings |
Rate limiting
| Code | Title |
|---|---|
ratelimited | Request was rate limited (HTTP 429) The request has been ratelimited. Refer to the Retry-After header for when to retry the request. |
rate_limited | Posting messages too quickly Application has posted too many messages, read the Rate Limit documentation for more information. |
message_limit_exceeded | Workspace message usage limit reached Members on this team are sending too many messages. For more details, see https://slack.com/help/articles/11500242294… |
Events API & webhooks
| Code | Title |
|---|---|
app_rate_limited | Events API deliveries rate limited "type": "app_rate_limited" |
url_verification | Request URL fails verification / events stop {"type": "url_verification", "challenge": "..."} |
Slack-side errors
| Code | Title |
|---|---|
fatal_error | Catastrophic error on Slack's side The server could not complete your operation(s) without encountering a catastrophic error. It's possible some aspect … |
internal_error | Transient 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… |
service_unavailable | Service temporarily unavailable The service is temporarily unavailable |
request_timeout | POST data missing or truncated The method was called via a POST request, but the POST data was either missing or truncated. |
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.