[BUG] Cloudflare WAF blocks OAuth token refresh from headless Linux servers — permanent lockout after ~1 hour

Open 💬 2 comments Opened Apr 14, 2026 by nosleepcassette

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Claude Code's OAuth token refresh is blocked by Cloudflare's WAF when the request originates from a headless Linux server. This is a distinct issue from #34917 (initial auth redirect failure) — this bug affects the token refresh path, meaning even after successful initial authentication, the session dies after ~1 hour with no way to recover without full manual re-authentication.

The failure

Tokens expire after approximately 1 hour (confirmed via expiresAt in ~/.claude/.credentials.json). When the CLI attempts to refresh, it sends:

  • Endpoint: POST https://platform.claude.com/v1/oauth/token
  • Content-Type: application/x-www-form-urlencoded
  • Parameters: grant_type=refresh_token, refresh_token=<token>, client_id=9d1c250a-e61b-44d9-88ed-5944d1962f5e

Response: HTTP 403 (Cloudflare WAF — bot/automated traffic detection) or HTTP 429 (rate limit after retries).

Cloudflare is classifying legitimate Claude Code CLI token refresh requests as bot traffic and blocking them. The same refresh works from macOS desktop environments where a browser context exists.

The result

  • Token expires → refresh blocked → permanent lockout
  • No --no-browser flag or stdin-based auth code entry exists
  • CLAUDE_CODE_OAUTH_TOKEN env var returns "OAuth is not currently supported"
  • API keys from claude.ai/settings are not accepted by Claude Code
  • The only recovery path is full manual re-authentication, which itself requires the broken browser-based flow on a headless system

Impact

I have been locked out of Claude Code on my primary development server (headless Ubuntu VPS) since March 18, 2026 — 26 days. I am a paying Pro subscriber. This is my production environment for nonprofit infrastructure work. I have spent 10+ hours troubleshooting this, including reverse-engineering PKCE parameters from Claude Code source, writing custom token exchange scripts, and running diagnostic sessions across multiple machines.

Support failure — please flag internally

I have filed three separate support tickets with Anthropic through official channels (March 24, March 29, and April 3, 2026). In every case I requested human escalation. I received a single automated "while we review your request" acknowledgment on March 24. I have not received a single human response in nearly three weeks. The Fin AI agent cannot resolve this — it is an infrastructure-level bug requiring engineering attention. If anyone from Anthropic sees this issue, please flag the associated support tickets internally. I should not have to use GitHub Issues as a support escalation path, but I have exhausted every other channel available to me as a Pro subscriber.

Related issues

  • #34917 — headless auth redirect failure (different root cause, same environment)
  • #29983 — headless code flow URL construction bug (closed as duplicate)
  • #7100 — feature request for documented headless auth path (open since Sept 2025, still unresolved)

What Should Happen?

Token refresh from the CLI should work regardless of whether the host has a browser. Cloudflare rules should allowlist the Claude Code CLI's user-agent and/or the OAuth token endpoint for non-browser clients.

Alternatively, provide any one of: (a) a --no-browser login flag, (b) working CLAUDE_CODE_OAUTH_TOKEN support, (c) API key support for Pro subscribers, or (d) documentation clearly stating that headless Linux is unsupported.

Error Messages/Logs

HTTP 403 from Cloudflare WAF on token refresh:

POST https://platform.claude.com/v1/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=<redacted>&client_id=9d1c250a-e61b-44d9-88ed-5944d1962f5e

Response: 403 Forbidden (Cloudflare)
Subsequent retries: 429 Too Many Requests

---

CLAUDE_CODE_OAUTH_TOKEN env var fallback:

"OAuth is not currently supported"

Steps to Reproduce

  1. SSH into a headless Ubuntu Linux VPS (no X11, no display server, no browser)
  2. Run claude auth login --claudeai and complete authentication manually (via copying the OAuth URL to a browser on another machine, completing the flow, and pasting the code back)
  3. Confirm authentication works — use Claude Code normally
  4. Wait approximately 1 hour for the access token to expire
  5. Observe that Claude Code attempts to refresh the token via POST to https://platform.claude.com/v1/oauth/token
  6. Refresh fails with HTTP 403 (Cloudflare WAF block) or HTTP 429 (rate limit on retry)
  7. Claude Code is now permanently locked out until full manual re-authentication (step 2), which itself requires the broken browser flow

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

1.0.85+

Platform

Anthropic API

Operating System

Ubuntu/Debian Linux

Terminal/Shell

iTerm2

Additional Information

I have filed three separate support tickets with Anthropic through official channels (March 24, March 29, and April 3, 2026). In every case I requested human escalation. I received a single automated "while we review your request" acknowledgment on March 24. I have not received a single human response in nearly three weeks. If anyone from Anthropic sees this issue, please flag the associated support tickets internally — I should not have to use GitHub Issues as a support channel, but I have exhausted every avenue available to me as a Pro subscriber.

Total lockout duration as of filing: 26 days.

Related issues:

  • #34917 — headless auth redirect failure (different root cause, same environment)
  • #29983 — headless code flow URL construction bug (closed as duplicate)
  • #7100 — feature request for documented headless auth path (open since Sept 2025, still unresolved)

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗