setup-token OAuth token returns 401 Invalid bearer token with claude -p on Max subscription (interactive login on same account works)

Status Fixed / completed
Maintainer reply None cached
Activity 3 comments · opened Jun 4, 2026 · closed Jun 4, 2026

Summary

A long-lived token from claude setup-token consistently returns API Error: 401 Invalid bearer token when used via CLAUDE_CODE_OAUTH_TOKEN with claude -p, even though interactive claude.ai login on the same single account (Max plan) works fine with claude -p. This blocks running a headless agent on a subscription, which is the documented purpose of setup-token.

Environment

  • Claude Code: v2.1.162
  • OS: Ubuntu 24.04 (VPS) and macOS — both reproduce
  • Node: v24
  • Plan: Max, single Anthropic account (no other accounts)
  • --bare not used; ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN both unset

Steps to reproduce

  1. On macOS: claude setup-token -> browser login (the only account, Max) -> token sk-ant-oat01-... (79 chars)
  2. export CLAUDE_CODE_OAUTH_TOKEN=<token>
  3. claude -p "hello"

Result:

Failed to authenticate. API Error: 401 Invalid bearer token

What I ruled out

  • Truncation / two-line copy-paste (#54738): token is exactly 79 chars; generated two separate tokens, both 79 -> full length, not truncated.
  • Machine-specific: fails identically on the VPS and on macOS with an isolated CLAUDE_CONFIG_DIR -> not environment-specific.
  • Account / plan: only one Anthropic account, Max plan, browser logged into that account during setup-token.
  • Env override (#34826): both ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY are unset.
  • --bare mode: not used (OAuth is not being skipped).
  • Decisive check: the same account via normal interactive claude.ai login (credential in ~/.claude) runs claude -p "AUTH OK" successfully. So headless -p on the subscription works in general — only the setup-token token is rejected.

claude auth status while using the token reports:

{"loggedIn": true, "authMethod": "oauth_token", "apiProvider": "firstParty"}

i.e. the token is accepted locally but rejected by the server on the actual API call.

Expected

The setup-token token authenticates claude -p on a Max subscription, per the docs (code.claude.com/docs/en/authentication, "Generate a long-lived token").

Actual

401 Invalid bearer token on every call, on two machines, with a fresh token.

Possibly related

  • #58926 — 401 auth loop, but that is Windows and all commands (incl. /login) fail; here interactive login works and only the setup-token path fails.
  • #54738 — two-line token wrap (ruled out here; token is full length).

View original on GitHub ↗

3 Comments

github-actions[bot] · 4 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/40860
  2. https://github.com/anthropics/claude-code/issues/54305
  3. https://github.com/anthropics/claude-code/issues/8938

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

greegorij · 4 months ago

Resolved — this was a truncated token on my side, not a server bug. Confirmed duplicate of #54738.

claude setup-token printed the token wrapped across two terminal lines and my copy captured only the first line. The genuine token is 108 chars; the one I tested was 79 — silently truncated at the terminal width. A second token I generated also came out 79 because it was the same terminal window wrapping at the same column, which is exactly why "both 79 chars" misled me into ruling truncation out (I never checked the true expected length).

Re-copied the full value with the embedded line break removed → claude -p now returns successfully on the Max subscription, headless. The loggedIn: true + 401 combination is the tell: the bearer string is accepted locally but rejected by the server because it's incomplete.

Closing as duplicate of #54738 (the real, actionable bug: setup-token should emit the token unwrapped). Thanks!

github-actions[bot] · 2 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.