All articles
AIClaude

Claude Code API Error 401 OAuth token has expired: 5 Proven Fixes (Tested)

Claude Code API Error 401 OAuth token has expired means the login token expired and the automatic refresh failed. We reproduced it on Claude Code 2.1.312 with a mock API and list the fixes for /login users, CLAUDE_CODE_OAUTH_TOKEN, scripts and the SDK.

Claude Code API Error 401 OAuth token has expired: a small clay hourglass with the sand run out, soft light and leaf shadows
Also available in

Short answer: Claude Code API Error 401 OAuth token has expired means the API rejected the login token Claude Code sent, because it expired and the automatic refresh didn’t work. The full line usually reads Please run /login · API Error: 401 OAuth token has expired. Please obtain a new token or refresh your existing token. Run /login and sign in again; that fixes most cases. If you set CLAUDE_CODE_OAUTH_TOKEN yourself (CI, scripts, Docker), /login alone won’t change what new sessions use: generate a new token with claude setup-token and replace the old value. We reproduced the error on Claude Code 2.1.312 with a mock API and an expired token; the output is below. Wording and fixes follow the official Claude Code error reference, checked on October 29, 2026.

What Claude Code API Error 401 OAuth token has expired means

Claude Code API Error 401 OAuth token has expired and similar messages: OAuth token revoked, Login expired, Invalid authentication credentials, Not logged in, with what each means

The docs group two messages together. OAuth token revoked · Please run /login means you signed out everywhere or an admin removed your access. Please run /login · API Error: 401 OAuth token has expired ... means the token expired and the automatic refresh failed mid-session. Both are rejections the API returned for a request Claude Code actually sent.

In -p mode and the Agent SDK the same error reads:

Failed to authenticate. API Error: 401 OAuth token has expired ...

and the structured error code is authentication_failed. Three nearby messages look similar but mean something else:

  • Login expired · Please run /login: Claude Code already failed to renew your saved login and cleared it, so it stops the request locally before sending it.
  • API Error: 401 Invalid authentication credentials: the token isn’t expired; the account, organization or API key behind it is no longer accepted.
  • Not logged in · Please run /login: no credential was found at all.

Our test: an expired token on every request

Claude Code API Error 401 OAuth token has expired reproduced against a mock API: claude -p fails with 401 while claude auth status still reports loggedIn true

We can’t make a real subscription token expire on demand, so we pointed Claude Code 2.1.312 at a local mock server with ANTHROPIC_BASE_URL. The mock answers every request with a 401 and the body {"type":"authentication_error","message":"OAuth token has expired. Please obtain a new token or refresh your existing token."}, the same text users quote in GitHub reports. We set CLAUDE_CODE_OAUTH_TOKEN to a dummy sk-ant-oat01-... value.

  • claude -p hi printed Failed to authenticate. API Error: 401 OAuth token has expired. Please obtain a new token or refresh your existing token. With --output-format json, the result had "is_error": true and "api_error_status": 401.
  • The mock logged 4 requests, all carrying Authorization: Bearer sk-ant-oat01-.... Claude Code kept sending the variable’s value, as the docs describe.
  • claude auth status still said "loggedIn": true, "authMethod": "oauth_token". That command only reports which credential is configured; it doesn’t check whether the token still works.
  • After unset CLAUDE_CODE_OAUTH_TOKEN with no saved login, the result was Not logged in · Please run /login. With an API key pointed at a mock that answers normally, the same prompt returned a reply.

For comparison, a malformed token sent to the real API returned API Error: 401 OAuth access token is invalid., which is a different message from expired.

How to fix Claude Code API Error 401 OAuth token has expired

Claude Code API Error 401 OAuth token has expired fix steps: /status, /login, claude setup-token, claude auth login in a new terminal, check the clock and claude doctor
  • Check which credential is active. Run /status. A token you set yourself shows as an Auth token row reading CLAUDE_CODE_OAUTH_TOKEN.
  • Saved login: run /login in the session and sign in again.
  • -p or Agent SDK with a saved login: run claude in the same environment, complete /login, then rerun your command.
  • CLAUDE_CODE_OAUTH_TOKEN: run claude setup-token on a machine with a browser, copy the token it prints, and replace the old value:
export CLAUDE_CODE_OAUTH_TOKEN=your-new-token

The docs say setup-token creates a one-year token and doesn’t save it anywhere. If the old value lives in your shell profile or the env block of a settings.json file, change it there too, or new sessions will keep reading it. Before v2.1.225, Claude Code could swap the variable’s value for a short-lived stored token mid-session, which then expired again; update if you’re older than that.

  • Automation without a browser: use ANTHROPIC_API_KEY instead, or a setup-token token.
  • Asked to log in on every launch: check that the system clock is right, since token validation depends on it. On macOS, run claude doctor and follow the Keychain steps in the login troubleshooting guide.

Pick the fix by how you sign in

Claude Code API Error 401 OAuth token has expired fix by sign-in method: saved /login, CLAUDE_CODE_OAUTH_TOKEN, API key

Since v2.1.210, /status also shows a Login row reading Expired — log in again when a saved login can’t be refreshed. The authentication docs add that Claude Code warns Your login expires in 3 days · run /login to renew at startup, so renewing then avoids a failure halfway through a long unattended task. If you still need to set up the CLI, start with our Claude Code install guide.

When /login doesn’t help: GitHub reports

These reports were filed on older versions and are now closed, but they describe what people ran into:

  • Issue #15007: after a 401 in an active session, /login completed in the browser but the session kept failing. One commenter on Windows said quitting and restarting Claude got them out.
  • Issue #44729: /login opened the browser but failed with OAuth error: timeout of 15000ms exceeded.
  • Issue #33291: in the VS Code extension, during a Claude incident on the status page, the reporter fixed it by running claude auth login in a terminal.

So if /login succeeds and the next prompt still fails, exit Claude Code, start it again (use claude --continue to get the conversation back) and retry. For browser sign-in problems in WSL2, SSH or containers, see the official steps. More errors are collected in our Claude Code errors hub.

FAQ

Does Claude Code API Error 401 OAuth token has expired mean my subscription ended?

No. It is about the login token. Removed access shows up differently: OAuth token revoked when an admin removes it, or Invalid authentication credentials when an account or organization is disabled.

Why does claude auth status say I’m logged in?

It reports which credential is configured, not whether the API still accepts it. Our test showed loggedIn: true with an expired token.

How long does a setup-token token last?

The docs say one year.

Will an API key fix it?

Yes, if you are fine paying API rates. An ANTHROPIC_API_KEY takes precedence over a subscription login (in interactive mode Claude Code asks once whether to use it); see our Claude usage limits guide for how subscription limits compare.

Leave a thought

Your email address will not be published.