Slack Error Guide: 'is_archived' — Posting to an Archived Channel
Fix the Slack is_archived error: detect archived channels before posting, unarchive when appropriate, reroute alerts to a live channel, and keep channel-id caches fresh, with real curl examples.
- #slack
- #api
- #troubleshooting
- #errors
Stuck on this Slack error? Get the free incident triage checklist
A one-page PDF — the exact steps to isolate, fix, and verify a production error like this one. No spam, unsubscribe anytime.
Overview
The is_archived error means you tried to act on a Slack channel that has been archived. Archived channels are read-only tombstones: Slack keeps the history but rejects new messages, membership changes, topic edits, and most writes. You will hit it from chat.postMessage, conversations.invite, conversations.setTopic, conversations.join, and similar methods when the target channel id points at an archived conversation. This is a state problem, not an auth or payload problem — the token and body are fine; the channel simply cannot be written to until it is unarchived.
The response is HTTP 200 with ok: false:
{
"ok": false,
"error": "is_archived"
}
It typically appears when a long-lived alert route, a saved channel id, or an automation targets a channel that a workspace admin archived after a team reorg or cleanup.
Symptoms
chat.postMessage(or another write) returns200with"error": "is_archived".- The failure is specific to one channel id; other channels work with the same token.
- Alerts silently stop landing in a channel that “used to work,” often after a channel-cleanup sweep.
conversations.infoon the channel shows"is_archived": true.
curl -s -X POST https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"channel":"C0ARCHIVED1","text":"deploy finished"}'
{
"ok": false,
"error": "is_archived"
}
Common Root Causes
1. The target channel was archived after the id was cached
An automation stores a channel id once. Weeks later an admin archives the channel; the id is still valid but writes now fail.
curl -s "https://slack.com/api/conversations.info?channel=C0ARCHIVED1" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
| python3 -c 'import sys,json;c=json.load(sys.stdin)["channel"];print("is_archived:",c["is_archived"])'
is_archived: true
2. Reusing a stale id from a renamed/replaced channel
A team spins up #alerts-v2 and archives #alerts, but the alert route still points at the old id.
curl -s "https://slack.com/api/conversations.info?channel=C0ARCHIVED1" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
| python3 -c 'import sys,json;c=json.load(sys.stdin)["channel"];print(c["name"], c["is_archived"])'
alerts True
3. Trying to invite or join an archived channel
Membership methods fail the same way — you cannot add the bot or users to an archived channel.
curl -s -X POST https://slack.com/api/conversations.join \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
-d '{"channel":"C0ARCHIVED1"}'
{"ok":false,"error":"is_archived"}
4. Editing topic/purpose on an archived channel
curl -s -X POST https://slack.com/api/conversations.setTopic \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
-d '{"channel":"C0ARCHIVED1","topic":"On-call: @alice"}'
{"ok":false,"error":"is_archived"}
5. A scheduled message firing after the channel was archived
chat.scheduleMessage accepted the message earlier, but by delivery time the channel is archived and the send fails.
curl -s "https://slack.com/api/conversations.info?channel=C0ARCHIVED1" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["channel"]["is_archived"])'
True
Diagnostic Workflow
Step 1: Confirm the channel is actually archived
curl -s "https://slack.com/api/conversations.info?channel=C0ARCHIVED1" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
{
"ok": true,
"channel": { "id": "C0ARCHIVED1", "name": "alerts", "is_archived": true }
}
is_archived: true confirms the state; if ok:false with channel_not_found, the id is wrong or the bot cannot see it — that is a different problem.
Step 2: Decide unarchive vs reroute
Check whether a live replacement channel already exists before unarchiving:
curl -s "https://slack.com/api/conversations.list?exclude_archived=true&limit=1000&types=public_channel,private_channel" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
| python3 -c 'import sys,json;[print(c["id"],c["name"]) for c in json.load(sys.stdin)["channels"] if "alert" in c["name"]]'
C0ALERTSV2 alerts-v2
Step 3: Unarchive if the channel should live again
conversations.unarchive needs the right scope and, for many workspaces, a user token with permission — a bot token often gets not_allowed_token_type or restricted_action.
curl -s -X POST https://slack.com/api/conversations.unarchive \
-H "Authorization: Bearer $SLACK_USER_TOKEN" -H "Content-Type: application/json" \
-d '{"channel":"C0ARCHIVED1"}'
{ "ok": true }
Step 4: Rejoin and confirm you can post
After unarchiving, the bot may need to rejoin before posting:
curl -s -X POST https://slack.com/api/conversations.join \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
-d '{"channel":"C0ARCHIVED1"}'
curl -s -X POST https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
-d '{"channel":"C0ARCHIVED1","text":"route restored"}'
{"ok":true,"ts":"1720000000.000100"}
Step 5: If rerouting, update the stored channel id
Point the automation at the live channel and re-test:
curl -s -X POST https://slack.com/api/chat.postMessage \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
-d '{"channel":"C0ALERTSV2","text":"route moved to alerts-v2"}'
{"ok":true,"ts":"1720000000.000200"}
Example Root Cause Analysis
A CI pipeline’s deploy notifier stops posting; the job logs show is_archived on every attempt. Checking the hardcoded channel id:
curl -s "https://slack.com/api/conversations.info?channel=C0DEPLOYOLD" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
| python3 -c 'import sys,json;c=json.load(sys.stdin)["channel"];print(c["name"], c["is_archived"])'
deploys True
A workspace cleanup archived #deploys and moved the team to #deploys-prod, but the pipeline’s SLACK_CHANNEL_ID was never updated. The notifier kept posting to a valid-but-archived id, so Slack rejected every message and no alert reached anyone. The fix is to repoint the pipeline variable at the live channel and add a startup preflight so this fails loudly next time:
STATE=$(curl -s "https://slack.com/api/conversations.info?channel=$SLACK_CHANNEL_ID" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["channel"]["is_archived"])')
[ "$STATE" = "True" ] && { echo "channel archived — update SLACK_CHANNEL_ID"; exit 1; }
With the id updated to #deploys-prod and a preflight check, deploy notifications resume and an archived route now surfaces as a clear build failure instead of silence.
Prevention Best Practices
- Preflight critical channel ids with
conversations.infoat startup and alert ifis_archivedis true — an archived route otherwise fails silently. - Prefer resolving channels by a stable identity (name-to-id lookup you refresh) over hardcoding ids that outlive the channel.
- On
is_archived, fall back to a designated live channel (or DM the owner) so an alert is never dropped just because its channel was archived. - Coordinate channel-archival cleanups with the teams whose automations post there; publish the replacement channel id.
- Give unarchive operations a user token with the right scope; bot tokens commonly cannot unarchive.
- Re-join with
conversations.joinafter unarchiving before assuming posts will land. - For quick triage of a stuck alert route, the free incident assistant can confirm whether the target channel is archived. See more in Slack guides.
Quick Command Reference
# Is the channel archived?
curl -s "https://slack.com/api/conversations.info?channel=C0ARCHIVED1" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
| python3 -c 'import sys,json;print(json.load(sys.stdin)["channel"]["is_archived"])'
# Find live replacement channels by name fragment
curl -s "https://slack.com/api/conversations.list?exclude_archived=true&limit=1000" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" \
| python3 -c 'import sys,json;[print(c["id"],c["name"]) for c in json.load(sys.stdin)["channels"] if "alert" in c["name"]]'
# Unarchive (user token, correct scope)
curl -s -X POST https://slack.com/api/conversations.unarchive \
-H "Authorization: Bearer $SLACK_USER_TOKEN" -H "Content-Type: application/json" \
-d '{"channel":"C0ARCHIVED1"}'
# Rejoin then post
curl -s -X POST https://slack.com/api/conversations.join \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" -H "Content-Type: application/json" \
-d '{"channel":"C0ARCHIVED1"}'
Conclusion
is_archived means the channel id is valid but the channel is a read-only tombstone. The usual root causes:
- A cached channel id whose channel was archived later.
- A stale id from a renamed or replaced channel.
- Trying to invite/join an archived channel.
- Editing topic/purpose on an archived channel.
- A scheduled message firing after archival.
Confirm with conversations.info, then either unarchive (with a user token and the right scope) and rejoin, or reroute to a live channel and update the stored id. Add a startup preflight so an archived route fails loudly instead of dropping alerts into a dead channel.
Fixed it? Get 500 Slack & DevOps AI prompts — free
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.
Did this fix your issue?
Get 500 Battle-Tested DevOps AI Prompts — Free
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.