Claude Code fix: Claude Code logged you out or says your login expired

Claude Code logged you out, or your login expired

To log out of Claude Code, type /logout at the Claude Code prompt, or run claude auth logout in a terminal. claude auth login signs you back in, and claude auth status says which login is active now. If you never logged out and Claude Code answers every request with Login expired and Please run /login, the saved login could no longer be refreshed. That usually has a findable cause, and a machine nobody has used for a while can also just look signed out while its login is fine.

Comes from Claude Code.

Diagnosis

What it actually is

Only the CLI refreshes the credential

The access token in ~/.claude/.credentials.json is renewed when Claude Code runs. Anything that reads the file without running the CLI sees an expired token and reports what it saw, which is why a model picker can go empty on a box whose login is perfectly good.

The login reached the end of its life

Claude Code warns at startup when a login is close to expiring, with Your login expires in 3 days and a prompt to run /login to renew. Once the stored login expires and cannot be refreshed, every model request fails with Login expired and Please run /login until you sign in again.

Two Claude Code windows refreshed at once

Refreshing rotates the credential, and only one process can do it at a time. Claude Code says so in its own words: Could not refresh your login because another Claude Code process is refreshing it (or exited mid-refresh), with advice to try again in a minute and close other windows if it keeps happening.

Refreshing it yourself is how a login really dies

The refresh token rotates, so a value replayed by two writers, a copied .credentials.json or a restored backup, is refused. Claude Code then reports OAuth token revoked and asks for /login. Nudging the CLI to refresh its own credential is the safe move, and doing the refresh on its behalf is the unsafe one.

/logout resets more than the login

Anthropic documents that logging out also resets your first-launch setup, so the next claude walks you through login and setup again. That is expected after a logout, not a sign that settings were lost.

An environment token keeps winning

CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY and ANTHROPIC_AUTH_TOKEN all rank above the login that /login saves. Running /login while one is set switches the current session, but every new session reads the variable again. That looks like Claude Code forgetting your login and is really the order it reads credentials in; the API key page covers it in full.

On macOS the Keychain refused the write

Claude Code keeps the login in the macOS Keychain. When the Keychain rejects the write, as it can when locked in an SSH session, Anthropic says Claude Code falls back to ~/.claude/.credentials.json. A Mac reached over ssh can therefore hold a different login from the one you see at the desk.

Check

Confirm it before you fix it

Run thisWhat a good answer looks like
claude auth statusRuns the CLI, which renews the credential as a side effect, and prints JSON by default: loggedIn, authMethod and the subscription type. Add --text for a readable Login method line plus the account email.
ls -l ~/.claude/.credentials.jsonOn Linux, and on a Mac where the Keychain fell back, this is the login. The modification time is the last refresh. A file untouched for days on a machine you thought was busy is the tell. On Windows the file is %USERPROFILE%\.claude\.credentials.json; on macOS it is normally in the Keychain instead.
[ -n "$CLAUDE_CODE_OAUTH_TOKEN" ] && echo set || echo unsetSays whether a long-lived token is set in this shell without printing it. set means every new session uses that token, whatever /login saved.

Every command here has been run on a real machine. Termdeck answers the same questions for every machine you have connected, without opening a terminal on any of them.

Fix

Cheapest thing first

1. Run the CLI once on that machine

One claude auth status is enough to renew a lapsed access token. It is also exactly what a well-behaved tool does instead of refreshing on the CLI behalf.

2. Sign in again with /login or claude auth login

Inside a session, /login. From a terminal, claude auth login, which uses your Claude subscription by default; --console signs in for Anthropic Console API billing instead, --sso forces single sign-on, and --email pre-fills the address.

3. Log out cleanly when you mean to

Inside a session, /logout. From a terminal, claude auth logout, which answers Successfully logged out from your Anthropic account. Expect the setup steps again on the next start.

5. Give headless machines a long-lived token

For CI, scripts or a box with no browser, claude setup-token generates a one-year token on a Pro, Max, Team or Enterprise plan. It does not save it anywhere: set it as CLAUDE_CODE_OAUTH_TOKEN in that environment. Remember to unset it later if you want /login to apply again.

6. Close the other windows if refresh keeps colliding

If the refresh error names another Claude Code process, finish or close the other windows, wait a minute, and run one session. Termdeck lists the sessions on a machine in one sidebar, including ones started in a terminal, which makes a forgotten window easier to spot.

Not this

What will not help

Deleting .credentials.json to force a fresh login

It works, and it throws away a refresh token that would have renewed on its own. Run the CLI first, and if you do want to sign out, use /logout or claude auth logout rather than deleting files.

Copying the credentials file to another machine

The refresh token rotates. Two machines holding one copy will spend it in turn and revoke each other. Sign in on each machine separately.

Signing in again while an API key is set

A key in the environment or a settings file ranks above the subscription login, so a fresh sign-in is ignored by every new session. Remove the key first.

FAQ

Claude Code logged you out or says your login expired, answered

How do I log out of Claude Code?

Type /logout at the Claude Code prompt, or run claude auth logout in a terminal. The next time you start claude it walks you through login and setup again.

How do I switch accounts in Claude Code?

Run claude auth logout, then claude auth login and sign in with the other account, then claude auth status --text to confirm which one is active. Inside a session, /logout and /login do the same.

Why does Claude Code log me out?

Usually it has not. The saved login reached its expiry and could not be refreshed, another Claude Code process was refreshing at the same moment, or a copied credentials file was revoked. Run claude auth status to see what it concludes.

Why does Claude Code keep asking me to log in?

Either the login cannot be refreshed, so every request says Login expired, or an environment variable such as CLAUDE_CODE_OAUTH_TOKEN or ANTHROPIC_API_KEY is overriding the login you just saved in every new session.

Where does Claude Code store its login?

On Linux in ~/.claude/.credentials.json with mode 0600. On macOS in the Keychain, falling back to that file if the Keychain refuses. On Windows in %USERPROFILE%\.claude\.credentials.json. CLAUDE_CONFIG_DIR moves the file.

How long does a Claude Code login last?

The access token lasts hours and is renewed whenever the CLI runs, so ordinary use never notices. Claude Code warns three days before the saved login itself expires. A token from claude setup-token lasts one year.

Why does the model list go empty when this happens?

Fetching models needs a working credential. An expired token fails that fetch, and an empty picker is the visible half of an auth problem.