Skip to content

Anthropic Claude Pro/Max OAuth login fails with 429 on token exchange #18329

Closed

Description

@dotCipher

Description

opencode auth login -p anthropic -m "Claude Pro/Max" consistently fails during the OAuth code exchange step with 429 Too Many Requests from https://console.anthropic.com/v1/oauth/token.

This is not just a generic Failed to authorize UI problem; with local debug logging enabled in the Anthropic auth plugin, the underlying failure is:

[opencode-anthropic-auth] OAuth exchange failed: status=429 statusText=Too Many Requests headers={...} body={
  "error": {
    "type": "rate_limit_error",
    "message": "Rate limited. Please try again later."
  }
}

I can reproduce this across multiple Anthropic accounts, which makes it look more like a flow-level / client-level / IP-level throttle than an account-specific Max-plan problem.

Environment

  • OpenCode version: 1.2.20
  • OS: macOS
  • Provider: anthropic
  • Login method: Claude Pro/Max

Steps to reproduce

  1. Run:
    opencode auth login -p anthropic -m "Claude Pro/Max" --print-logs --log-level DEBUG
  2. Open the provided claude.ai/oauth/authorize URL in the browser.
  3. Complete login successfully in Claude.
  4. Paste the returned authorization code back into OpenCode.
  5. Observe Failed to authorize.

What is happening underneath

The browser authorization step succeeds and returns a code.

The failure happens on the follow-up token exchange to:

  • POST https://console.anthropic.com/v1/oauth/token

The plugin currently collapses that HTTP failure into a generic Failed to authorize message.

Related behavior

Earlier in the same session, Anthropic OAuth refresh was also failing for prompt traffic with:

Error: Token refresh failed: 429

So both fresh login and refresh appear to be failing on the Anthropic OAuth/token path.

Notes

  • Anthropic status page was nominal at the time.
  • We also tested changing the outgoing User-Agent for Anthropic requests locally, but the 429 still occurred.
  • The response did not include a Retry-After header or obvious Anthropic rate-limit reset metadata, only generic front-door headers.

Request

It would help a lot if OpenCode could:

  1. Surface the real OAuth exchange status/body instead of only Failed to authorize.
  2. Clarify whether this Anthropic OAuth flow is still supported / expected to work for Claude Pro/Max.
  3. Potentially make the Anthropic auth/user-agent behavior configurable for debugging.

If helpful, I can provide the exact debug patch used to expose the hidden exchange error.

Activity

  1. github-actions commented on Mar 20, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    Please review those issues to see if your problem is already being tracked, and consider adding your findings there instead.

  2. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Mar 20, 2026
  3. dotCipher commented on Mar 20, 2026

    @dotCipher
    Author

    Wrote a user agent configuration plugin to solve this actually, it did end up working: https://github.com/dotCipher/opencode-anthropic-user-agent-plugin

  4. dotCipher commented on Mar 20, 2026

    @dotCipher
    Author

    Follow-up: I was able to work around this locally by changing the Anthropic-facing User-Agent, and that resolved the login issue for me.

    So at least in my case, this does not appear to be a generic bad auth-code problem. It looks more like the Anthropic OAuth/token exchange path was sensitive to the client fingerprint / user-agent being sent by OpenCode on this flow.

    What I observed:

    • claude.ai/oauth/authorize succeeded
    • the failure was on POST https://console.anthropic.com/v1/oauth/token
    • after overriding the Anthropic-facing User-Agent, the flow started working

    I packaged the workaround as a small OpenCode plugin here:

    This may help narrow the root cause:

    1. OpenCode's Anthropic auth flow may be sending a User-Agent that triggers throttling / rejection on Anthropic's token exchange path.
    2. It may be worth making the Anthropic User-Agent configurable for debugging.
    3. It would still be helpful for OpenCode to surface the real exchange response instead of only Failed to authorize.
  5. Nick-Hopps commented on Mar 20, 2026

    @Nick-Hopps

    not work for me. btw the oAuth domain has changed to platform.anthropic.com

  6. lehdqlsl commented on Mar 20, 2026

    @lehdqlsl

    I tried your user-agent plugin first — thanks for the detailed root cause analysis. In my case the OAuth flow itself was broken regardless of UA, so I took a different approach: syncing existing Claude CLI credentials directly into OpenCode's auth store, skipping the OAuth login entirely.

    Not an npm package — plain shell scripts (~100 lines) you can audit before running. No supply chain risk.

    Repo: https://github.com/lehdqlsl/opencode-claude-auth-sync

  7. vinzabe commented on Mar 20, 2026

    @vinzabe
  8. DerDummePunkt commented on Mar 20, 2026

    @DerDummePunkt

    I'm not sure this will be fixed :/
    #18186

  9. JlMoreno00 commented on Mar 20, 2026

    @JlMoreno00

    Tested a working workaround on macOS with OpenCode 1.2.27 and Claude Code 2.1.80.

    This does not fix the built-in Anthropic login flow itself, but it did restore Anthropic usage end-to-end here:

    1. Remove local Anthropic patches/plugins from OpenCode (custom auth plugins, user-agent overrides, prompt spoof plugins).
    2. Remove the stale Anthropic entry from OpenCode auth storage.
    3. Re-auth Claude CLI with claude auth login --claudeai.
    4. Sync Claude CLI credentials into OpenCode using opencode-claude-auth-sync:
      https://github.com/lehdqlsl/opencode-claude-auth-sync
    5. Verify the sync script reports a valid token before testing OpenCode.

    Important detail: if the sync script reports EXPIRED, syncing will not help. Refresh Claude CLI first, then sync again.

    After doing that, this worked:

    opencode run --model anthropic/claude-sonnet-4-0 "Reply only with OK"

    Result:

    OK

    So the reliable workaround for me was: use Claude CLI as the source of truth for Anthropic OAuth, then sync those fresh credentials into OpenCode instead of relying on OpenCode's Anthropic login flow.

  10. MoerAI commented on Mar 20, 2026

    @MoerAI

    Fix Available

    The root cause of this 429 on token exchange has been identified and fixed in the opencode-anthropic-auth plugin:

    Two issues in opencode-anthropic-auth v0.0.13:

    1. Wrong Content-Type: Token exchange and refresh requests use application/json with JSON.stringify(), but Anthropic's /v1/oauth/token endpoint expects application/x-www-form-urlencoded (per OAuth 2.0 RFC 6749 §4.1.3).

    2. Missing User-Agent header (primary cause of 429): The plugin sets User-Agent: claude-cli/2.1.2 (external, cli) for API calls but omits it from token exchange/refresh requests. Anthropic's token endpoint rate-limits requests that don't match the expected Claude CLI request shape.

    PR with fix: ex-machina-co/opencode-anthropic-auth#12

    After applying both changes, opencode auth login → Anthropic → Claude Pro/Max successfully obtains tokens and Claude models work correctly.

    cc @nichochar @julian-opencode

  11. ultism commented on Mar 20, 2026

    @ultism
  12. ggi-svg commented on Mar 20, 2026

    @ggi-svg

    This is not an error ! Claude his blocking opencode now for legal reason se PR : #18186
    What a shame ....

    I just canceled my subscrption to claude and i m now switching to ChatGPT Plus !

    Image
  13. MoerAI commented on Mar 20, 2026

    @MoerAI

    Update: OpenCode has officially dropped Claude support

    Hi everyone — I want to provide an important update to clarify the situation here, as there seem to be many workarounds being shared that may no longer be relevant.

    On March 20, 2026, Dax (OpenCode lead) announced on X that OpenCode is officially removing Claude OAuth support, following a formal legal request from Anthropic. The relevant commit is titled "Anthropic legal requests" and redirects users to alternative providers (OpenAI, GitHub, GitLab, etc.).

    What this means

    • The 429 errors on token exchange were not a bug — they were Anthropic deliberately rate-limiting third-party OAuth clients at the token endpoint level
    • Anthropic's updated ToS (February 2026) explicitly prohibits using Claude Free/Pro/Max OAuth tokens outside of Claude Code and claude.ai
    • My earlier PR (fix: use form-urlencoded and Claude CLI User-Agent for OAuth token requests ex-machina-co/opencode-anthropic-auth#12) addressed a real technical issue (wrong Content-Type + missing User-Agent), and it did make login succeed temporarily — but the underlying policy decision from Anthropic means this is not a sustainable path forward

    For those still looking for solutions

    • Anthropic API keys (pay-per-token) still work with OpenCode — this is the only officially supported method
    • OpenAI, Google, GitHub Copilot OAuth remain fully functional alternatives within OpenCode
    • Credential sync workarounds may work today but carry ToS violation risk

    I'm closing my PR accordingly. Thank you to everyone who helped investigate this issue.

  14. lehdqlsl commented on Mar 20, 2026

    @lehdqlsl

    Quick update on my workaround repo (opencode-claude-auth-sync): I shipped v0.3.1 to clarify and fix the refresh semantics.

    Claude CLI does not proactively rotate tokens just because they are near expiry; it refreshes once the token is actually expired/unusable. The repo/docs now match that verified behavior.

    Upgrade:

    curl -fsSL https://raw.githubusercontent.com/lehdqlsl/opencode-claude-auth-sync/main/install.sh | bash

    Release: https://github.com/lehdqlsl/opencode-claude-auth-sync/releases/tag/v0.3.1

  15. 5 remaining items

  16. shahidshabbir-se commented on Mar 21, 2026

    @shahidshabbir-se

    @g14wx The 429 on token exchange means you're on an older version that used the wrong User-Agent.

    Update to the latest:

    npm install -g opencode-anthropic-oauth@latest

    Verify you're on v0.3.0:

    npm list -g opencode-anthropic-oauth

    Add to your opencode.json:

    {
      "plugin": ["opencode-anthropic-oauth@latest"]
    }
    

    Then clear OpenCode's plugin cache and retry:

    rm -rf ~/.cache/opencode/node_modules/opencode-anthropic-oauth
    oc auth login

    v0.3.0 uses the correct User-Agent: claude-cli/2.1.80 on the token exchange — the old versions used User-Agent: anthropic which Anthropic blanket-rejects with 429.

  17. ErcinDedeoglu commented on Mar 21, 2026

    @ErcinDedeoglu

    @g14wx The 429 on token exchange means you're on an older version that used the wrong User-Agent.

    Update to the latest:

    npm install -g opencode-anthropic-oauth@latest
    Verify you're on v0.3.0:

    npm list -g opencode-anthropic-oauth
    Add to your opencode.json:

    {
      "plugin": ["opencode-anthropic-oauth@latest"]
    }
    

    Then clear OpenCode's plugin cache and retry:

    rm -rf ~/.cache/opencode/node_modules/opencode-anthropic-oauth
    oc auth login
    v0.3.0 uses the correct User-Agent: claude-cli/2.1.80 on the token exchange — the old versions used User-Agent: anthropic which Anthropic blanket-rejects with 429.

    king. share your donate link!

  18. vinzabe commented on Mar 21, 2026

    @vinzabe
  19. g14wx commented on Mar 21, 2026

    @g14wx

    Wow seriously thanks a lot @shahidshabbir-se , what a detailed solution

    thank you so much!

  20. dotCipher commented on Mar 23, 2026

    @dotCipher
    Author

    For anyone still hitting OAuth issues with Anthropic, I built opencode-claude-bridge which combines fixes from several community plugins into one. It auto-syncs tokens from Claude CLI's keychain (zero-click if you're already logged in), handles token refresh, and emulates Claude Code's exact request format. Install: just add "plugin": ["opencode-claude-bridge"] to your OpenCode config — it auto-installs from npm.

  21. mateusz28011 commented on Mar 23, 2026

    @mateusz28011

    For anyone still hitting OAuth issues with Anthropic, I built opencode-claude-bridge which combines fixes from several community plugins into one. It auto-syncs tokens from Claude CLI's keychain (zero-click if you're already logged in), handles token refresh, and emulates Claude Code's exact request format. Install: just add "plugin": ["opencode-claude-bridge"] to your OpenCode config — it auto-installs from npm.

    On opencode 1.3 i have this error "Anthropic API key is missing. Pass it using the 'apiKey' parameter or the ANTHROPIC_API_KEY environment variable."

  22. dotCipher commented on Mar 23, 2026

    @dotCipher
    Author

    @mateusz28011 file an issue on my project if you have problems and I'll look into them on a case-by-case basis

  23. skhaz commented on Mar 23, 2026

    @skhaz

    I had the same issue.

  24. dotCipher commented on Mar 23, 2026

    @dotCipher
    Author

    Update for OpenCode 1.3+ — opencode-claude-bridge v1.6.1

    For those still hitting issues (especially after the OpenCode 1.3 update that removed the built-in Anthropic plugin), I've released v1.6.1 of opencode-claude-bridge with several fixes:

    What was breaking on OpenCode 1.3:

    • The removal of the built-in Anthropic provider meant that OAuth requests were no longer automatically injecting a required x-anthropic-billing-header system block — Anthropic's API silently rejects these requests without it
    • Some users saw "Anthropic API key is missing" because the SDK required a non-empty key at initialization time even during OAuth flows
    • Model selection could break if the plugin's auth loader threw during provider initialization

    What v1.6.1 fixes:

    • Injects the x-anthropic-billing-header system block automatically (required for OAuth on OpenCode 1.3)
    • Sets a placeholder ANTHROPIC_API_KEY instead of deleting it, so the SDK initializes cleanly — the real Authorization: Bearer token is set in the request headers by the fetch wrapper
    • Guards provider.models access in case OpenCode 1.3 passes an incomplete provider object during model selection

    Install / upgrade:

    { "plugin": ["opencode-claude-bridge"] }

    Or upgrade manually:

    cd ~/.cache/opencode && npm install opencode-claude-bridge@latest

    Then restart OpenCode. If you're logged into Claude CLI (claude login), it auto-syncs your credentials — no re-auth needed.

    @mateusz28011 and @skhaz — the "API key missing" error should be resolved in v1.6.1.

  25. Sleepful commented on Mar 31, 2026

    @Sleepful
    Contributor

    brew upgrade opencode :)

  26. dotCipher commented on Apr 16, 2026

    @dotCipher
    Author

    Closing, as this is not supported directly by opencode anymore, see thread: #18267

    I wrote a plugin for opencode to support my use case, released here: https://github.com/dotCipher/opencode-claude-bridge

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

coreAnything pertaining to core functionality of the application (opencode server stuff)

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions