Slack API Error Guide: 'invalid_auth' Token Authentication Failed
Fix the Slack API invalid_auth error: diagnose malformed tokens, wrong token type, missing Bearer header, uninstalled apps, and rotated credentials with curl.
- #slack
- #troubleshooting
- #errors
- #authentication
Overview
The invalid_auth error means Slack could not authenticate the token you presented. The credential is malformed, truncated, sent the wrong way, or no longer valid for the workspace. It is a hard authentication failure — Slack rejects the request before any scope or channel logic runs. This differs from not_authed (no token was supplied at all) and token_revoked (a once-valid token was explicitly killed).
You will see this in the JSON body of essentially any Web API call:
{
"ok": false,
"error": "invalid_auth"
}
It occurs at the authentication layer, so the fastest reproduction is auth.test, which exists solely to validate a token.
Symptoms
- Every API call returns
ok: falsewitherror: invalid_auth. auth.testfails, not just one endpoint.- The app was uninstalled/reinstalled and old tokens stopped working.
- A token copied from CI or a secret store fails but the dashboard value works.
curl -s "https://slack.com/api/auth.test" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
{
"ok": false,
"error": "invalid_auth"
}
Common Root Causes
1. The token is truncated or has stray whitespace
A token clipped on copy, or with a trailing newline injected by a shell or secret manager, fails authentication. Slack bot tokens begin with xoxb-, user tokens with xoxp-.
printf '%s' "$SLACK_BOT_TOKEN" | head -c 6; echo
printf '%s' "$SLACK_BOT_TOKEN" | wc -c
xoxb-
57
If the prefix is wrong or the length looks too short, the stored value is corrupt.
2. The Authorization header is malformed
Forgetting the Bearer prefix, or putting the token in the URL instead of the header, breaks auth.
# Wrong: missing "Bearer "
curl -s "https://slack.com/api/auth.test" \
-H "Authorization: $SLACK_BOT_TOKEN"
{
"ok": false,
"error": "invalid_auth"
}
The correct form is -H "Authorization: Bearer $TOKEN".
3. The app was uninstalled or reinstalled
Uninstalling an app invalidates its tokens; reinstalling issues new ones. An old token cached in CI keeps failing.
curl -s "https://slack.com/api/auth.test" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
{
"ok": false,
"error": "invalid_auth"
}
Re-copy the current Bot User OAuth Token from the app’s OAuth & Permissions page.
4. Wrong token for the endpoint family
A legacy/deprecated token, an app-level token (xapp-) used for a Web API call, or a signing secret pasted as a token all fail. Web API calls need xoxb-/xoxp-.
printf '%s' "$SLACK_TOKEN" | cut -c1-5
xapp-
xapp- is a Socket Mode app-level token, not valid for auth.test Web API auth.
5. The token belongs to a deleted/disabled workspace or app
If the workspace was deleted or the app disabled by an admin, the token can no longer authenticate anywhere.
curl -s "https://slack.com/api/auth.test" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
{
"ok": false,
"error": "invalid_auth"
}
Cross-check by testing a known-good token from the same app; if that works, the failing one is stale.
6. Environment variable not exported / empty
A shell that never exported the variable sends an empty token, which Slack reads as invalid auth.
echo "len=${#SLACK_BOT_TOKEN}"
len=0
A length of 0 means the variable is unset in this process.
Diagnostic Workflow
Step 1: Validate the token shape locally
printf '%s' "$SLACK_BOT_TOKEN" | sed -E 's/^(xox.-....).*/\1.../'
printf '%s' "$SLACK_BOT_TOKEN" | wc -c
Confirm the xoxb-/xoxp- prefix and that there is no trailing newline (the printf avoids adding one).
Step 2: Call auth.test in isolation
curl -s "https://slack.com/api/auth.test" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
auth.test removes scope/channel variables; if it fails, the problem is purely the token or header.
Step 3: Re-test with a freshly copied token
SLACK_BOT_TOKEN='xoxb-...freshly-copied...' \
curl -s "https://slack.com/api/auth.test" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN"
{
"ok": true,
"team": "ACME Prod",
"user_id": "U0BOTBOT01"
}
If the fresh token works, your stored/CI value is stale or corrupt.
Step 4: Confirm the header form
curl -sv "https://slack.com/api/auth.test" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" 2>&1 | grep -i '> authorization'
> authorization: Bearer xoxb-xxxxxxxx...
Ensure the literal word Bearer and a single space precede the token.
Step 5: Rotate and redeploy if still failing
If a valid header with a clean token still fails, regenerate the token from the app dashboard, update the secret store, and redeploy. Then re-run auth.test to confirm ok: true.
Example Root Cause Analysis
A nightly job that calls chat.postMessage starts failing with invalid_auth after a secret rotation. Posting the same payload from a laptop works.
Inspecting the CI value:
printf '%s' "$SLACK_BOT_TOKEN" | wc -c
58
The laptop’s token is 57 characters; CI’s is 58. Dumping the last byte reveals a trailing newline the secret store appended:
printf '%s' "$SLACK_BOT_TOKEN" | tail -c 1 | xxd
00000000: 0a .
The 0a (newline) at the end corrupts the Authorization header, so Slack rejects it.
Fix: store the token without a trailing newline (e.g. printf '%s' when writing the secret), then re-run:
curl -s "https://slack.com/api/auth.test" -H "Authorization: Bearer $SLACK_BOT_TOKEN"
{"ok": true, "team": "ACME Prod", "user_id": "U0BOTBOT01"}
Prevention Best Practices
- Store tokens without trailing whitespace/newlines and verify length on deploy; a single stray byte is the most common cause.
- Always use the
Authorization: Bearer <token>header — never the deprecatedtokenquery parameter or a bare header value. - Run
auth.testas a startup health check so a stale or uninstalled-app token fails fast at boot, not mid-incident. - Keep token type straight:
xoxb-for bot Web API,xoxp-for user Web API,xapp-only for Socket Mode connections. - After any uninstall/reinstall, treat all previously issued tokens as dead and re-pull the current ones into your secret store.
- For ad-hoc triage, the free incident assistant can tell a malformed-token failure apart from a revoked one. See more in Slack guides.
Quick Command Reference
# Validate token shape without adding a newline
printf '%s' "$SLACK_BOT_TOKEN" | cut -c1-5
printf '%s' "$SLACK_BOT_TOKEN" | wc -c
# The canonical auth check
curl -s "https://slack.com/api/auth.test" -H "Authorization: Bearer $SLACK_BOT_TOKEN"
# Inspect the actual header sent
curl -sv "https://slack.com/api/auth.test" \
-H "Authorization: Bearer $SLACK_BOT_TOKEN" 2>&1 | grep -i '> authorization'
# Check for a trailing newline
printf '%s' "$SLACK_BOT_TOKEN" | tail -c 1 | xxd
Conclusion
invalid_auth is a clean authentication failure: Slack does not accept the token as presented. The usual root causes:
- A truncated token or one with stray whitespace/newlines.
- A malformed Authorization header (missing
Bearer). - An app that was uninstalled/reinstalled, invalidating old tokens.
- The wrong token type for the endpoint (e.g.
xapp-on a Web API call). - A deleted workspace or admin-disabled app.
- An unset/empty environment variable sending no real token.
Reproduce with auth.test, verify the token shape and header, and re-pull a fresh credential if needed — the fix is almost always restoring a clean, current token.
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.