Slack API Error Guide: 'channel_not_found' Invalid or Inaccessible Channel
Fix the Slack API channel_not_found error: diagnose wrong channel IDs, cross-workspace tokens, deleted channels, name-vs-ID confusion, and DM access with curl.
- #slack
- #troubleshooting
- #errors
- #channels
Overview
The channel_not_found error means Slack cannot resolve the channel value you passed to a conversation that this token is allowed to see. Either the ID is malformed, the channel was deleted, the token belongs to a different workspace, or the bot has no visibility into a private conversation. Unlike not_in_channel (the channel exists but the bot is not a member), channel_not_found means the API does not return the channel at all for this token.
You will see this in the JSON body:
{
"ok": false,
"error": "channel_not_found"
}
It occurs on almost any conversation endpoint — chat.postMessage, conversations.history, conversations.info, conversations.invite — whenever the supplied channel reference does not map to a conversation visible to the calling token.
Symptoms
chat.postMessagereturnsok: falsewitherror: channel_not_found.conversations.infofor the same ID also returnschannel_not_found.- The same ID works with a different app’s token but not yours.
- A channel that worked yesterday now returns the error (deleted/archived).
curl -s "https://slack.com/api/conversations.info?channel=C0XXXXXXXXX" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
{
"ok": false,
"error": "channel_not_found"
}
Common Root Causes
1. The channel ID is wrong or malformed
A typo, truncated ID, or a value with stray whitespace will not resolve. Valid IDs start with C (public/private channel), G (legacy private group), or D (DM).
curl -s "https://slack.com/api/conversations.list?types=public_channel,private_channel&limit=200" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" | head -30
{
"ok": true,
"channels": [
{"id": "C0123456789", "name": "deploys"},
{"id": "C0198765432", "name": "alerts"}
]
}
If your target ID is not in this list, it does not exist for this token.
2. The token belongs to a different workspace
Channel IDs are workspace-scoped. A token from workspace B cannot see workspace A’s channels, even if the ID is valid there.
curl -s "https://slack.com/api/auth.test" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
{
"ok": true,
"team_id": "T0AAAAAAA",
"team": "ACME Prod",
"user_id": "U0BOTBOT01"
}
If team_id is not the workspace that owns the channel, you will always get channel_not_found.
3. The channel was deleted or its ID changed
A deleted channel disappears entirely. Archived channels still resolve via conversations.info, but a truly deleted one returns channel_not_found.
curl -s "https://slack.com/api/conversations.list?types=public_channel&exclude_archived=false&limit=200" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" | grep C0XXXXXXXXX
(no output)
No match in the full (including archived) list means the channel is gone.
4. A channel name was passed instead of an ID
Passing #deploys or deploys instead of C0123456789 does not resolve on most modern endpoints, which require the ID.
curl -s -X POST https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel":"#deploys","text":"hi"}'
{
"ok": false,
"error": "channel_not_found"
}
Resolve the name to an ID with conversations.list first.
5. A private channel the bot cannot see
Private channels are invisible to a bot that is not a member, so conversations.info returns channel_not_found rather than revealing the channel’s existence.
curl -s "https://slack.com/api/conversations.list?types=private_channel&limit=200" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
{
"ok": true,
"channels": []
}
An empty private list (when private channels do exist) means the bot has not been invited to any.
6. Missing the scope to read that conversation type
Without channels:read / groups:read / im:read, the corresponding conversations are invisible and resolve as not found.
curl -s "https://slack.com/api/conversations.info?channel=C0123456789" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
{
"ok": false,
"error": "missing_scope",
"needed": "channels:read",
"provided": "chat:write"
}
A bare channel_not_found alongside missing read scopes points at the scope gap.
Diagnostic Workflow
Step 1: Confirm which workspace the token is in
curl -s "https://slack.com/api/auth.test" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
Match team_id/team against the workspace that owns the channel. A mismatch is the answer.
Step 2: List conversations and search for the ID
curl -s "https://slack.com/api/conversations.list?types=public_channel,private_channel&exclude_archived=false&limit=1000" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
| grep -o '"id":"C[0-9A-Z]*","name":"[^"]*"'
If your target ID appears, it exists for this token; if not, it is wrong, deleted, or invisible.
Step 3: Probe the specific ID directly
curl -s "https://slack.com/api/conversations.info?channel=C0XXXXXXXXX" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
channel_not_found here, with a valid token, narrows it to deleted / wrong-workspace / private-invisible.
Step 4: Resolve a name to a canonical ID
curl -s "https://slack.com/api/conversations.list?types=public_channel&limit=1000" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
| grep -o '"id":"C[0-9A-Z]*","name":"deploys"'
"id":"C0123456789","name":"deploys"
Use that id everywhere instead of the name.
Step 5: Verify scopes and retry
curl -s "https://slack.com/api/auth.test" -H "Authorization: Bearer $SLACK_BOT_TOKEN"
# After fixing ID/scope:
curl -s "https://slack.com/api/conversations.info?channel=C0123456789" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
{
"ok": true,
"channel": {"id": "C0123456789", "name": "deploys"}
}
Example Root Cause Analysis
A staging notifier that worked for months suddenly logs channel_not_found for every post. The token still authenticates:
curl -s "https://slack.com/api/auth.test" -H "Authorization: Bearer $SLACK_BOT_TOKEN"
{"ok": true, "team_id": "T0AAAAAAA", "team": "ACME Prod", "user_id": "U0BOTBOT01"}
The token is valid and in the right workspace. Searching the full conversation list, including archived, for the hard-coded ID returns nothing:
curl -s "https://slack.com/api/conversations.list?exclude_archived=false&limit=1000" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" | grep C0DELETED99
(no output)
Someone deleted the old #staging-notify channel and created a new one with a fresh ID. The hard-coded ID no longer exists.
Fix: resolve the new channel by name and update the config:
curl -s "https://slack.com/api/conversations.list?limit=1000" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
| grep -o '"id":"C[0-9A-Z]*","name":"staging-notify"'
"id":"C09NEWCHAN1","name":"staging-notify"
Point the notifier at C09NEWCHAN1 and posts succeed again.
Prevention Best Practices
- Resolve channel names to IDs at deploy time and store the
C…ID; never hard-code a#nameinto API calls. - Validate the token’s
team_idmatches the target workspace during startup, so cross-workspace token swaps fail loudly. - Cache
conversations.listand refresh it onchannel_deleted/channel_renameevents so stale IDs are caught immediately. - Grant the read scopes (
channels:read,groups:read) that match the conversation types you address, so visibility never silently drops. - Distinguish
channel_not_found(resolve/visibility problem) fromnot_in_channel(membership problem) in your error handling — the fixes differ. - For ad-hoc triage, the free incident assistant can separate a deleted-channel failure from a wrong-workspace token. See more in Slack guides.
Quick Command Reference
# Which workspace is this token in?
curl -s "https://slack.com/api/auth.test" -H "Authorization: Bearer $SLACK_BOT_TOKEN"
# Does the ID exist (including archived)?
curl -s "https://slack.com/api/conversations.list?exclude_archived=false&limit=1000" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" | grep C0XXXXXXXXX
# Probe a specific channel
curl -s "https://slack.com/api/conversations.info?channel=C0XXXXXXXXX" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
# Resolve a name to an ID
curl -s "https://slack.com/api/conversations.list?limit=1000" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
| grep -o '"id":"C[0-9A-Z]*","name":"deploys"'
Conclusion
channel_not_found means the channel reference does not resolve to a conversation this token can see. The usual root causes:
- A wrong, truncated, or whitespace-padded channel ID.
- A token from a different workspace than the channel’s.
- A channel that was deleted (its ID no longer exists).
- A
#namepassed where the API expects aC…ID. - A private channel the bot has never been invited to.
- Missing read scopes for that conversation type.
Confirm the token’s workspace, search the conversation list for the ID, and resolve names to canonical IDs — the channel reference is the single variable to nail down.
Download the Free 500-Prompt DevOps AI Toolkit
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.