[BUG] OAuth token refresh returns persistent 429 for headless automation account (1 call/4h, started ~March 20)
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?
Our production automation system uses a dedicated Claude Max ($200/mo) account running 35 scheduled tasks on Windows Task Scheduler. A single script refreshes the OAuth token via platform.claude.com/v1/oauth/token on a fixed schedule — 6 calls/day, evenly spaced every 4 hours. ONE call per trigger. No retries.
Starting approximately March 20, 2026, this endpoint began returning persistent HTTP 429 (Too Many Requests). The same script, same schedule, same volume worked flawlessly from initial setup through March 19. We have 8 days of logs showing 100% success before the change, and persistent failures after.
Once the first 429 hits, the token expires, all 35 automation tasks fail, and manual claude login is the only recovery path. We've had 4 outages in 5 days, each requiring manual recovery. When traveling or OOO, there is no way to recover remotely.
Call volume: 6 OAuth refresh calls per day total. This is the most conservative possible refresh pattern and it still gets rate-limited.
What Should Happen?
A headless automation account making 6 token refresh calls per day (1 every 4 hours) to platform.claude.com/v1/oauth/token should succeed reliably. Token refresh is critical infrastructure — it should not share a rate bucket with usage/monitoring endpoints, and 6 calls/day should be well within any reasonable limit.
Ideally: (1) separate rate limits for /v1/oauth/token refresh vs usage/status endpoints, (2) a stable headless auth mechanism for automation accounts (API keys don't expire), or (3) documented rate limits so automation builders can design around them.
Error Messages/Logs
Error Messages/Logs:
Token refresh log showing the transition from working to broken:
=== March 19 (WORKING — last good day) ===
[2026-03-19 19:45:03] Attempting OAuth refresh for automation...
[2026-03-19 19:45:03] Refresh succeeded for automation - token now expires in 8h
=== March 20 (BROKEN — first 429) ===
[2026-03-20 02:00:02] Attempting OAuth refresh for automation...
[2026-03-20 02:00:02] Refresh FAILED for automation: The remote server returned an error: (429) Too Many Requests.
[2026-03-20 03:15:03] Attempting OAuth refresh for automation...
[2026-03-20 03:15:03] Refresh FAILED for automation: The remote name could not be resolved: 'platform.claude.com'
=== March 21-24: persistent 429s, 4 full outages requiring manual claude login ===
[2026-03-24 00:00:03] 429 error (failure 1/3). Next scheduled trigger will retry.
[2026-03-24 04:00:02] 429 error (failure 2/3). Next scheduled trigger will retry.
[2026-03-24 06:31:41] AUTH EXPIRED: automation token expired 3.3h ago. Task Sunrise-DailyCloseOut skipped.
[2026-03-24 06:45:09] FLEET-CRITICAL: SYSTEMIC FAILURE - 5 tasks failed in 2h
Steps to Reproduce
Steps to Reproduce:
- Create a dedicated Claude Max account for automation (separate from interactive use)
- Authenticate via
claude loginto obtain OAuth tokens - Set up a scheduled script that calls the OAuth refresh endpoint:
POST https://platform.claude.com/v1/oauth/token
Body: { grant_type: "refresh_token", refresh_token: "<token>", client_id: "9d1c250a-e61b-44d9-88ed-5944d1962f5e" }
- Schedule this to run 6x daily (every 4 hours) — well within any reasonable rate limit
- Observe: refresh calls return 429 Too Many Requests, even as the first and only call in a 4-hour window
- Token expires, all downstream automation fails, manual
claude loginis the only recovery
This worked perfectly from setup through March 19, 2026. Started failing March 20 with no changes on our side.
Claude Model
Opus
Is this a regression?
Yes, this worked in a previous version
Last Working Version
Worked through March 19, 2026. Broke March 20. No client-side version change.
Claude Code Version
2.1.77+ (Current 2.1.81)
Platform
Other
Operating System
Windows
Terminal/Shell
Non-interactive/CI environment
Additional Information
Additional Information:
## Related Issues
- #31021 — OAuth usage API persistent 429
- #30930 — Persistent 429 for Max users (retry-after: 0)
- #31637 — Usage endpoint aggressively rate limits
- #10784 — OAuth expiration retry storm
- #30616 — Session startup triggers 429 on client_data
All point to the same root cause: OAuth endpoints rate-limited too aggressively for legitimate production use. Our
case is distinct because we're making the absolute minimum number of calls (6/day) on a dedicated headless account and
still hitting the limit.
## Architecture Context
- Windows 11 Pro for Workstations (dedicated server, 256GB RAM)
- 35 scheduled tasks depending on valid OAuth token
- Single Writer Guardian pattern: one script, one mutex, one attempt per trigger, circuit breaker after 3 consecutive
429s
- Automation account is headless — zero interactive sessions competing for rate limit
- We've already optimized to the theoretical minimum call volume. There is nothing left to reduce.
## The Ask
Production Claude Code automation users need a reliable headless auth path. The current OAuth flow is designed for
interactive use where a human can re-login. Headless automation has no human in the loop — when refresh breaks,
everything breaks until someone physically intervenes.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗