Skip to main content
Claudebeginner

Fix "OAuth token has expired" in Claude Code — Session Expired, Run /login

Fix `OAuth token has expired` and `Your session has expired. Please run /login to sign in again.` in Claude Code. Re-authenticate, clear stale credentials, unset conflicting keys.

8 min readUpdated August 2026

Claude Code stops working and reports that your credentials are no longer valid. Depending on where the failure occurs, you will see one of these:

Your session has expired. Please run /login to sign in again.
Failed to authenticate: OAuth session expired and could not be refreshed
OAuth token expired and refresh failed (re-login required)

All three describe the same condition. The token Claude Code holds is dead, and the automatic refresh that normally renews it in the background was refused.

Why This Happens

When you sign in, Claude Code receives a short-lived access token and a longer-lived refresh token. The access token expires routinely, and Claude Code exchanges the refresh token for a new one without telling you. That silent renewal is why you can normally go weeks without seeing a login prompt.

You only see this error when the refresh itself fails. That happens for a handful of reasons:

  • The session was revoked. Changing your password, signing out of claude.ai, or an administrator terminating sessions invalidates the refresh token everywhere.
  • The machine was offline or asleep too long. If the refresh token itself ages out before the client can use it, there is nothing left to renew.
  • The stored credential is corrupt or unreadable. A partially written credentials file, or a macOS Keychain that is locked or not writable, means Claude Code cannot read or persist tokens.
  • A conflicting API key. An ANTHROPIC_API_KEY in your environment competes with subscription login and can leave authentication in an inconsistent state.
  • A badly wrong system clock. Token validity is time-bound; a clock off by hours makes a valid token look expired.

Fix 1: Log In Again

Start here. Inside a Claude Code session:

/login

Your browser opens for the OAuth flow. Complete it, return to the terminal, and the session should resume.

This must be run from an interactive terminal — Claude Code will refuse the flow otherwise, since it needs to open a browser and wait for you.

Fix 2: Log Out First, Then Log In

If /login alone does not stick, the stored credential is likely stale rather than merely expired. Discard it explicitly:

/logout
/login

/logout signs you out of your Anthropic account and clears the cached credential, so the next login writes a completely fresh token instead of trying to reconcile a broken one. This two-step cycle resolves most cases that a bare /login does not.

Fix 3: Remove a Conflicting API Key

This is the most common reason the error returns immediately after a seemingly successful login. If ANTHROPIC_API_KEY is set, Claude Code may use it instead of your subscription session — and it will say so directly, telling you to unset the variable and run /login to sign in with your claude.ai account.

Check what is set:

env | grep -E "ANTHROPIC_API_KEY|ANTHROPIC_AUTH_TOKEN"

Clear it and retry:

unset ANTHROPIC_API_KEY
unset ANTHROPIC_AUTH_TOKEN
claude

If that fixes it, remove the export from your shell profile as well — ~/.zshrc, ~/.bashrc or ~/.profile — otherwise it returns the next time you open a terminal:

grep -rn "ANTHROPIC_API_KEY" ~/.zshrc ~/.bashrc ~/.profile 2>/dev/null

Note that Claude Code also supports an apiKeyHelper setting, which can reintroduce a key even when the environment looks clean. Check your settings if the variable is genuinely gone but the behaviour persists.

Advertisement

Fix 4: Fix Credential Storage

Claude Code needs somewhere writable to persist a refreshed token. If it cannot write, every launch looks like a fresh expiry.

On macOS, credentials live in the login Keychain. Claude Code reports distinct errors — Keychain access denied or Keychain is not writable — when this is the problem. Unlock the login keychain in Keychain Access, confirm it is not set to lock automatically after a short idle period, and approve the access prompt when it appears.

On Linux and Windows, credentials are stored in a .credentials.json file under your Claude directory:

ls -la ~/.claude/.credentials.json

If the file is owned by root — usually the legacy of an installation run with sudo — Claude Code cannot rewrite it:

sudo chown $(whoami) ~/.claude/.credentials.json
chmod 600 ~/.claude/.credentials.json

As a last resort, delete the file and log in again to regenerate it:

rm ~/.claude/.credentials.json
claude
# then: /login

For a full map of where Claude Code keeps its state, see where configuration files are stored.

Fix 5: Check the System Clock

A clock that is significantly wrong makes valid tokens appear expired and can break the TLS handshake outright.

# macOS / Linux
date

# Force a time sync on macOS
sudo sntp -sS time.apple.com

# On Linux with systemd
sudo timedatectl set-ntp true

This is a rare cause on a laptop, but a common one in virtual machines and containers that have been suspended and resumed.

Fix 6: Rule Out a Proxy or Firewall

If the OAuth callback cannot reach Anthropic, login appears to succeed in the browser but never completes in the terminal. Behind a corporate proxy:

export HTTPS_PROXY="http://proxy.company.com:8080"
export HTTP_PROXY="http://proxy.company.com:8080"
claude
# then: /login

TLS-inspecting proxies are a frequent culprit here, since they present their own certificate to the client. If you can authenticate on a personal network but not on the corporate one, the network path is the problem rather than your credentials — see fixing permission and authentication errors for related network troubleshooting.

Verify the Fix

Confirm you are actually authenticated rather than merely unblocked:

/status

This shows the version, current model, account and API connectivity in one view. A populated account line and working connectivity means the token is valid.

For a broader check of the installation:

claude doctor

Then send a short message. A normal response confirms the session is live.

Prevention

  • Do not mix authentication methods. Pick either subscription login or an API key on a given machine. Keeping ANTHROPIC_API_KEY set "just in case" while logging in with claude.ai is the single most common cause of recurring authentication trouble.
  • Never install with sudo. Root-owned credentials and config files cause failures that look like expiry but are permission problems.
  • Use API keys for anything headless. CI runners, servers and containers cannot complete an interactive OAuth flow. Issue a key from the Anthropic console for those environments.
  • Re-authenticate deliberately after a password change. Changing your password invalidates existing sessions, so run /login once afterwards instead of waiting to be interrupted mid-task.
  • Keep clocks synced on VMs and containers that get suspended.

Frequently Asked Questions

Find answers to common questions

The access token Claude Code stored when you logged in is no longer valid, and the refresh attempt failed. Claude Code normally renews tokens silently in the background; you only see this message when the renewal itself was refused, which means a full re-login is required.

Run /login inside Claude Code and complete the browser sign-in. If that fails, run /logout first to discard the stale credentials, then /login again. A clean logout-then-login cycle resolves the large majority of cases.

Refresh can fail for reasons unrelated to age: a password change, signing out of claude.ai elsewhere, an admin revoking sessions, a system clock that is significantly wrong, or a machine that was asleep or offline past the refresh window. Any of these invalidates the stored token regardless of how recently you signed in.

The most common cause is an ANTHROPIC_API_KEY environment variable competing with your subscription login. Claude Code will tell you to unset the variable and run /login to sign in with your claude.ai account. Remove it from your shell profile, not just the current session, or it comes back at the next terminal launch.

On macOS they go into the login Keychain. On Linux and Windows they are written to a .credentials.json file in your ~/.claude directory. If the Keychain is locked or not writable, Claude Code cannot persist a refreshed token and the session appears to expire on every launch.

You cannot — the OAuth flow needs an interactive terminal and a browser. Claude Code says as much when you try. On a headless server or in CI, use API key authentication with a key issued from the Anthropic console instead of an interactive subscription login.

Usually not. An expired token is a credential problem, not a billing one. Billing problems surface with their own distinct messages about credit balance or usage limits. If /login completes successfully and you can still work, your subscription is fine.

An expired token means Claude Code cannot prove who you are, and the fix is re-authenticating. A rate limit means you are authenticated but have used your allowance, and the fix is waiting for the reset or changing plan. The two errors are unrelated.