Headless CLI sends empty then wrong Authorization bearer instead of provided OAuth credentials (401 Invalid bearer token), machine-specific
Summary
On one of my two Macs, headless claude -p cannot authenticate with valid Max-subscription OAuth credentials. The CLI does not send the credential it was given. Captured on the wire: the first request goes out with an empty bearer (Authorization: Bearer with nothing after it), and retries carry a different 108-character credential that is not the one provided and does not exist anywhere on disk. The API rejects it with 401 Invalid bearer token. The identical CLI version on my other Mac sends the provided token correctly and works.
Environment
- Failing machine: Mac mini (arm64), macOS Darwin 25.x, headless (SSH only). Native install.
- Reproduced on CLI versions 2.1.119, 2.1.206, and 2.1.207 (native installer builds).
- Working machine: MacBook (arm64), CLI 2.1.206, same account, same token.
- Auth under test: Max 20x subscription OAuth, tried both ways:
CLAUDE_CODE_OAUTH_TOKENenv var fromclaude setup-token.credentials.jsonwritten by a successful interactive/login(subscriptionType max, correct rate limit tier)
Evidence
- The OAuth token itself is valid from the failing machine: a raw
curl https://api.anthropic.com/v1/messages -H "Authorization: Bearer <token>"returns HTTP 200 from the same box, with or without the oauth beta header. - Wire capture (pointed
ANTHROPIC_BASE_URLat a local HTTP sink and logged headers): firstPOST /v1/messages?beta=truearrives withAuthorization:value of exactly 6 characters, i.e. the literal stringBearerwith an empty token. Subsequent attempts carry a 115-character value ("Bearer " + 108 chars) whose hash does not match "Bearer " + the provided token. The same ghost value is sent on every run, across freshCLAUDE_CONFIG_DIRs and even a throwawayHOME. Anx-api-keyheader is also present on these requests alongsideAuthorization. - The working machine's capture shows the correct "Bearer " + provided token on the first request.
Ruled out on the failing machine
- Keychain: the
Claude Code-credentialsgeneric password was deleted; behavior unchanged; the entry stays absent. - Stored state: brute-force hashed every token-shaped string in
~/.claude.json, config dirs, statsig, caches; the ghost credential matches none of them. - Env: no
ANTHROPIC_API_KEY,ANTHROPIC_AUTH_TOKEN, proxy vars, or launchd setenv values present. - Managed settings: none.
apiKeyHelper: removed from the equation via cleanCLAUDE_CONFIG_DIRand via throwawayHOMEwith only.credentials.json+ minimal settings; still 401. - Clock skew: zero versus the API's Date header.
Odd data point
Immediately after creating a clean profile, one invocation on 2.1.119 authenticated successfully with the env token. Every attempt after that, on all versions, fails as described. This made it look intermittent at first; it has been 100 percent reproducible since.
Impact
Headless automation on this machine cannot use subscription auth at all; it only works with API-key billing. Happy to run diagnostic builds or provide the capture tooling.