Troubleshooting

Fixing Claude Code Login Expired and Repeated Logouts

Claude Code asking for a login once is routine. Asking repeatedly, across every open terminal at the same moment, is a specific failure with a specific cause — and a recovery order that works better than guessing.

Published Updated 7 minute read

Limit Lifeboat showing a Claude Code account whose saved login has expired, with a Log In action available.
An expired login stays actionable instead of silently reporting stale usage.

What actually causes the logout loop

OAuth refresh tokens are single-use by design: redeeming one issues a new access token and a new refresh token, and invalidates the old one. That is a security property, not a bug. It becomes a problem when two things hold a copy of the same refresh token and both try to use it.

One wins and rotates the token. The other presents a token that has already been spent, and the provider rejects it. If the losing process treats that rejection as "this login is dead" rather than "someone else already rotated it", the stored credential gets cleared — and now every session on the machine is logged out at once, not just the one that lost the race.

That is why the symptom has such a distinctive shape:

  • Several terminals demand a login at the same moment, not one at a time.
  • It often happens right after waking the Mac from sleep, when everything reconnects together.
  • You logged in only recently, so a genuine expiry does not explain it.
  • It recurs, because the same conditions reproduce it.

Parallel sessions, a background tool that also refreshes credentials, and the same account signed in on more than one Mac all increase the odds. This is a real enough failure mode that Limit Lifeboat shipped a fix for its own contribution to it in version 1.1.1, and reduced cross-machine expiry in 1.0.4.

Recovery, in order

Work down this list and stop at the first step that works. Each is more disruptive than the last.

  1. Run /login inside Claude Code. It renews in place, without a logout first, and resolves most cases. Try this before anything else.
  2. Full cycle. Run /logout, close the terminal window completely rather than just exiting Claude Code, open a new one, start claude, and log in. Closing the terminal matters — it clears first-run state that a plain restart keeps.
  3. Close every other session first. If the loop keeps returning, shut down all other Claude Code sessions and any background tool that reads credentials, then log in once with nothing else running. This removes the race rather than working around it.
  4. Clear the stored credential. Remove Claude Code's saved credential and authenticate from a clean state. On macOS the login lives in the Keychain item Claude Code-credentials rather than in a plain file.
  5. Use an API key temporarily. Setting ANTHROPIC_API_KEY bypasses OAuth completely. It moves you onto metered API billing, so treat it as a way to finish something urgent rather than a resolution.

Two things worth knowing while you do this. Re-authenticating replaces authentication only — your settings.json, MCP servers, hooks, permissions and history are not involved. If those did disappear around the same time, something else was responsible, and recovering a lost MCP configuration covers what. And keep Claude Code itself up to date: token-refresh handling has been improved more than once, and an old version can reproduce a problem that has already been fixed upstream.

Avoiding a repeat

  • Be deliberate about parallel sessions. Several Claude Code instances on one account is the single biggest contributor. If you need genuine parallelism, tools that give each profile an isolated configuration directory avoid sharing one credential between them.
  • Audit what else touches your credentials. Any background tool that refreshes tokens is a participant in the race. It should back off when another writer has already rotated, rather than overwriting.
  • Watch the same account across machines. Two Macs signed into one account will rotate the same token from different places.
  • Keep Claude Code current. Refresh-race handling has improved over time.

This is also the behaviour to look for in any account switcher. A tool that overwrites a credential another process just rotated will cause exactly this problem. Limit Lifeboat treats a newer external change as authoritative: if something else rewrote the credential mid-switch, the switch aborts rather than overwriting it, and background usage refreshes never rotate the live CLI login at all. The switcher comparison covers how the alternatives handle it.

When a saved account shows as expired

If you keep several accounts and one of them shows an expired login or a stale usage figure, that is a different situation from being logged out of the active session. A saved credential for an account you are not currently using can expire on its own, the Keychain can refuse background access to it, or a provider request can simply fail.

The right behaviour from a tool here is to say so. Limit Lifeboat keeps the last successful reading, shows how old it is, and marks anything over 30 minutes as stale rather than presenting it as current. Recoverable Claude credentials refresh silently; a login that the provider has genuinely rejected surfaces a Log In action instead of failing in the background. Reauthenticating that account through the official flow and refreshing the app restores it.

More on reading usage accurately in why usage numbers disagree, and if the problem turns out to be capacity rather than authentication, see what to do when the limit is reached. If the login works but names the wrong account, checking which account is active is the faster route.

Questions and boundaries

Why does Claude Code keep asking me to log in again?

The most common cause of repeated logouts is two things refreshing the same login at once. Refresh tokens are single-use: when one process redeems the token, the other's copy becomes invalid, and the failed attempt can invalidate the stored login rather than just failing quietly. Waking a Mac from sleep with several sessions open is a reliable way to trigger it.

Does /login fix an expired Claude Code session?

Usually, and it should be your first attempt. /login renews in place without needing a logout first and resolves most expiry cases. Only escalate to a full logout, terminal restart, and fresh login if renewing in place fails.

Will re-logging in lose my settings or MCP servers?

No. Logging in again replaces authentication only. settings.json, MCP server definitions, hooks, permissions, and local history are unaffected. What does lose configuration is a script that swaps entire configuration directories, which is a different problem.

Why does an inactive saved account show an expired login?

Saved credentials can expire on their own, the Keychain can deny background access, or a provider request can fail. A tool showing that account can only report its last successful reading. Limit Lifeboat shows the age of that reading and offers a Log In action rather than presenting stale data as live.

Why am I logged out every morning?

An overnight logout usually means the token needed renewing while the machine was asleep or offline, and the renewal either never ran or several sessions attempted it together on wake. The shape to look for is whether every terminal demands a login at once, which points at a rotation race rather than an ordinary expiry. Closing sessions you are not using before you finish for the day reduces it.

Should I switch to an API key instead?

Setting ANTHROPIC_API_KEY bypasses the OAuth flow entirely and will stop the logout loop, but it moves you onto metered API billing rather than your subscription. It is a reasonable emergency measure, not a fix for the underlying cause.

Free and open source

Keep an expired login actionable.

Monitor usage and switch deliberately without replacing the rest of your setup.

Download for Mac