[BUG] Claude code requires users to constantly login

Open 💬 73 comments Opened Jun 7, 2025 by scrapebros
💡 Likely answer: A maintainer (ant-kurt, collaborator) responded on this thread — see the highlighted reply below.

[BUG] Claude code requires users to constantly login

Claude code requires user to authenticate using the web almost every day which is excessive and unnecessary, should not be required to do this every day

Get this screen when I just authenicated last night:
╭──────────────────────────╮
│ ✻ Welcome to Claude Code │
╰──────────────────────────╯

██████╗██╗ █████╗ ██╗ ██╗██████╗ ███████╗
██╔════╝██║ ██╔══██╗██║ ██║██╔══██╗██╔════╝
██║ ██║ ███████║██║ ██║██║ ██║█████╗
██║ ██║ ██╔══██║██║ ██║██║ ██║██╔══╝
╚██████╗███████╗██║ ██║╚██████╔╝██████╔╝███████╗
╚═════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝
██████╗ ██████╗ ██████╗ ███████╗
██╔════╝██╔═══██╗██╔══██╗██╔════╝
██║ ██║ ██║██║ ██║█████╗
██║ ██║ ██║██║ ██║██╔══╝
╚██████╗╚██████╔╝██████╔╝███████╗
╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝

Browser didn't open? Use the url below to sign in:

claude --version
1.0.9 (Claude Code)

View original on GitHub ↗

73 Comments

ant-kurt collaborator · 1 year ago

That is definitely not right! Which option are you using to sign in - Anthropic Console or a Claude subscription? What OS are you running? There are some differences in how the credentials are managed - e.g. MacOS stores as a keychain entry.

scrapebros · 1 year ago

This is claude code with a max subscription (I have the 20X and 5X subscriptions happens on both).

I'm seeing this behavior across multiple machines, they're all on:
root@ai-code:~# uname -a
Linux ai-code 6.8.12-9-pve #1 SMP PREEMPT_DYNAMIC PMX 6.8.12-9 (2025-03-16T19:18Z) x86_64 x86_64 x86_64 GNU/Linux
root@ai-code:~#

michael-hedgineer · 1 year ago

I saw this quite a bit a couple weeks ago but not as much starting last week.

dwymark · 1 year ago

I'm seeing this too. It comes up multiple times a day at random times. I'm using nvm managed node in WSL2.

nikomatsakis · 1 year ago

Me as well. Recent change in behavior and very frustrating. Occurs in both WSL and on my Darwin machine; in both cases I am using a locally installed claude in ~/.claude.

emregunel · 1 year ago

I am having the same issue.

  • Claude Code Max
  • Ubuntu machine (no wsl)
igorkofman collaborator · 1 year ago

What version of claude (claude --version), (claude update) are you folks running - could you ensure you are on latest?
Anything specific that triggers it (updating settings, having multiple session in parallel?)

max-sixty · 1 year ago
What version of claude (claude --version), (claude update) are you folks running - could you ensure you are on latest? Anything specific that triggers it (updating settings, having multiple session in parallel?)

for me — it's when I use the same .claude path for linux & mac — the mac version deletes .credentials.json — log at https://github.com/anthropics/claude-code/issues/1414

scrapebros · 1 year ago

1.0.6 (Claude Code)

I am not sure this is the root cause for me, but I have noticed it seems to happen more when the SSH session ends or if I get into a situation where I;m experiencing #1422 and have to use control-c or control-z to escape it.

Is something overwriting the file or editing it after authentication and messing up the stored key? That'd be my guess but haven't investigated it.

dwymark · 1 year ago

I always update to the latest version as soon as it's available. I tend to run 3-4 sessions on the same wsl2 instance at a given time. Unclear what the exact trigger is.

Another thing I have noticed is that the theme will change from light to dark around the same time that this bug occurs. This will happen mid-session sometimes, and the next Claude I open shows me the oauth prompt.

dinhphieu · 1 year ago

Same for me in WSL2. It seems like it happens more when I use Ctrl+C to exit a session. I'm using ZSH and remoting into IntelliJ on WSL2 via JetBrains Gateway

cjoelrun · 1 year ago

Not sure of the cause. I constantly have trouble with claude path when installing to local and switch back to global, I think this was somehow causing login to constantly trigger. Reinstalling to local fixed this for me.

svilupp · 11 months ago

I have the same issue all the time! I connect to my laptop via SSH and have to re-login every time

Yelles · 10 months ago

Same issue (at least once a day on Xcode 26 beta 7), it drove me so crazy that I switched to ChatGPT even though I prefer Claude...

Not to mention the fact that despite my max plan, I quickly reach the limit, whereas with ChatGPT+, which is much cheaper, I've never been blocked (on a Swift project).
(and this is definitely not to promote them, because I much prefer Claude, but it's becoming increasingly unusable as a developer...)

romanathappymoney · 10 months ago

same issue. I have a feeling this is related somehow to utilization. I've upped my usage in the recent weeks, hitting multiple opus limits and noticed that "turns" got a lot slower during higher utilization times. I am pretty sure that is somehow Antropic combating account sharing issues and whatever other usage policy vilolations might be there.

whatformat · 9 months ago

I'm getting 401 errors daily since the upgrade to the new claude code. I previously didn't have to reauth after my very first authentication when setting claude code up.

Running Sequoia 15.6.1 (24G90),

VSCode Version: 1.105.0 (Universal)
Commit: 03c265b1adee71ac88f833e065f7bb956b60550a
Date: 2025-10-08T14:09:35.891Z
Electron: 37.6.0
ElectronBuildId: 12502201
Chromium: 138.0.7204.251
Node.js: 22.19.0
V8: 13.8.258.32-electron.0
OS: Darwin arm64 24.6.0

Edited to also add: I've never been close to claude limits as far as I'm aware, I don't think it's that.

undo-git-pull · 8 months ago

Same issue with Claude vscode plugin, login using pro subscription.

tmatei · 8 months ago

same issue +1

jvlobo · 8 months ago

I'm having the same issue since I updated to the new Visual Studio Code extension that now shows instead of the terminal. It is the most annoying thing ever... After I write my whole prompt I get the damn

``API Error: 401 {"type":"error","error":{"type":"authentication_error","message":"OAuth token has expired. Please obtain a new token or refresh your existing token"} · Please run /login``

Will this be fixed at some point? Can I go back to the previous VSCode extension?

yusufmalikul · 8 months ago

happen to me, need to /login almost every morning.
claude version: 2.0.25 (Claude Code)
macos intel: MacBook Pro (Retina, 15-inch, Mid 2015)

ViktorTrojan · 8 months ago

fix this already ...

The problem is that the auth token is only valid for like ~6 hours, maybe a bit more and after it expires the refresh tokens job is to refresh it. But it simply does not do that.

Thats literally what oauth is ment to do and they messed that up somehow.

BenHMatrix · 8 months ago

Same issue, sounds like @ViktorTrojan is onto something, anyone @claude looking at this?

FrenchMajesty · 8 months ago

Experiencing this issue way more recently as well. I have to login every day whereas I used to not. I have a Max subscription, using Claude Code on the latest VSCode extension that has the GUI.

wongjustin99 · 8 months ago

This is happening to me after logging in just 10 minutes ago. It kicked me out, and then suddenly started kicking me out aggressively.

ndurell · 7 months ago

Just noting I started seeing this issue last week. I'm on v2.0.61. I'm using the subscription option to login.

thclark · 7 months ago

It's SO annoying having to log in several times each day seemingly once per day per project - flitting between 5-10 repos means I'm doing this workflow 5-10 times per day.

jellefoks · 7 months ago

it looks like the OAUTH token expires in only about 8 hours or so.

se1961 · 6 months ago

Same issue here. Reauthenticate every day.

danr · 6 months ago

~Same here, many logins every week, gets quite tedious.~

Edit: I have to relogin because my firejail sandboxing cannot refresh the oauth token. Without the sandbox I can refresh it. I have not yet figured out how to make the refresh work in the sandbox.

Deracination · 6 months ago

Same here, need to login every morning

Shwapx · 6 months ago

Same issue need to login every day

Mangosteen-Yang · 5 months ago

same here

shifoc · 5 months ago

this keeps happening and it's very frustrating

gertzgal · 5 months ago

Same here

pushchris · 5 months ago

Happening to me every single day, unbelievably annoying

nicolas-scb · 5 months ago

Same here, happens multiple times a day. Read somewhere about possible corrupt claude.json file, but deleting it hasn't fixed the issue for me. (v2.1.15)

uladzk · 5 months ago

same here
I have to re-login few times a day and it's annoying.
working on Mac, Claude Code CLI latest version (2.1.17)

yarikoptic · 5 months ago

I thought that I had addressed this by switching to some other means of authentication from that token one, but forgot how, and now this came back, and I found this almost year old issue?! wow... may be should finally consider another platform for my 200$/mo since support seems to be lacking

sasa-fajkovic · 5 months ago

@claude - Please go fix this long-lasting and annoying issue. Prioritize it as highest prio. @bcherny can help increasing priority on this issue

yarikoptic · 5 months ago

I wonder now if that is a "feature" that tokens produced within claude code is just short lived , and you need a dedicated run of claude setup-token to produce the one with duration of 1 year (seems to require providing it via CLAUDE_CODE_OAUTH_TOKEN env var... yet to figure that detail out since I think it worked without before!)

matthew-plusprogramming · 5 months ago

This is also an issue for me. I seem to get logged out every few days

nayan-mehta · 5 months ago

Same here, stops working after every coffee break!

Samuel-Isirima · 5 months ago

Same here. I'm asked to authenticate almost every 6 hours.
The account is on two different laptops, so does this have anything to do with refresh tokens?
This needs to be fixed.

alvinycheung · 5 months ago

Same, getting this right now.

mzxrai · 5 months ago

Seeing this too.

sulavtimsina · 5 months ago

@claude Can you fix this? It's a real problem.

prosdev · 5 months ago

Seeing this consistently on ghostty. Didn't experience this before on item2. I am on claude max plan

shamsTabrezamu · 5 months ago

I had the same worry until I saw this. Max plan user, using Claude in Ghostty, and I have to /login daily.

keyvhinng · 4 months ago

It started to happen from a week ago. Now I'm required to log in daily

ivg-design · 4 months ago

+1 here

just started seeing thsi after recent auto-update

kidandcat · 4 months ago

Same here, Max plan, Claude code on Mac. It happens in my Mac logged in with the browser, and in my cloud, using the OAuth token (claude setup-token, which it says it last for 1 year....).

nikitakreskinsemrushcom · 4 months ago

This issue really disturbs my workflow, hitting this error multiple times a day. Max plan, mac (darwin), v2.1.56

Igarez · 4 months ago

Same here, constant authentication

jhwheeler · 4 months ago

Now it's happening multiple times per session for me, randomly in the middle of the session.

jcrodriguezu · 4 months ago

It started to happen today for me, multiple times per session as well

mattgperry · 4 months ago

Same - at least once per day. Also logs out mcps

Albermonte · 4 months ago
Same - at least once per day. Also logs out mcps

Same here, logget out of Claude Code and MCPs, I did a clean install and this is still happening.
Tried bew version and direct install, both with same problem

Igarez · 4 months ago

Root cause found + fix: .claude.json corruption causes infinite re-auth loop

My environment: Windows 11 native (not WSL), Claude Code Max subscription, multiple parallel terminal sessions.

Note: The root cause (.claude.json corruption) and the fix below apply to any OS — the ~/.claude/ directory structure is the same on Windows, macOS, and Linux. My trigger was concurrent sessions on Windows, but yours could be SSH disconnects, Ctrl+C exits, or cross-platform sharing — the corrupted file and the fix are identical regardless.

What happened

I was running 3-4 Claude Code sessions simultaneously in separate terminal windows (same machine, same .claude directory). After a few days of this workflow, Claude Code started asking me to re-authenticate every single time I opened a new terminal.

Diagnosis

I investigated ~/.claude/backups/ and found 68 .corrupted backup files of .claude.json, with a clear escalation pattern:

| Date | Corrupted files |
|------|----------------|
| Feb 19 | 1 |
| Feb 26 | 25 |
| Feb 27 | 42 |
| After fix | 0 |

The corrupted files ranged from 43 bytes to 22KB (normal size is ~22KB). The small files were partial writes — clear evidence of a race condition between concurrent sessions writing to the same .claude.json simultaneously:

// 43 bytes — partial write, only one field survived
{"changelogLastFetched": 1772188173438}

// 77 bytes — slightly more, but still truncated
{"clientDataCache": {"data": {}, "timestamp": 1772134977126}}

// 157 bytes — has userID but missing everything else (tokens, settings, tips, etc.)
{"clientDataCache": {"data": {}, "timestamp": 1772134961074}, "userID": "9903fa..."}

What's happening: Multiple Claude Code sessions read/write ~/.claude/.claude.json without file locking. When two sessions write at the same time, one truncates the file mid-write, and the other reads an incomplete JSON. Claude Code detects the corruption, moves it to backups/, and creates a new file — but this new file is missing the auth tokens (which now live in .credentials.json since ~v2.x). The next session reads the new .claude.json, doesn't find tokens, and asks you to log in again. Repeat forever.

The fix

# 1. Check if you already have valid credentials (you probably do)
cat ~/.claude/.credentials.json
# If this file exists and has content (accessToken, refreshToken, etc.), your tokens are fine.
# The problem is .claude.json, not your actual credentials.

# 2. Stop ALL Claude Code sessions (close every terminal window)

# 3. Remove the corrupted .claude.json
mv ~/.claude/.claude.json ~/.claude/.claude.json.broken

# 4. Start Claude Code once
claude
# It will regenerate a clean .claude.json and read tokens from .credentials.json
# You should NOT be asked to log in again.

# 5. Verify: open a second terminal, run claude — no login prompt = fixed

If .credentials.json is also missing or empty, delete both files and run claude — it will do a fresh login and create both files cleanly.

Why this works

Since ~v2.x, Claude Code stores authentication tokens in .credentials.json (not .claude.json). The .claude.json file stores preferences, tips history, startup count, etc. When .claude.json gets corrupted by concurrent writes, Claude Code gets confused about auth state even though the actual tokens in .credentials.json are perfectly valid. Removing the corrupted file lets Claude Code rebuild it cleanly.

Note on the 2.1.61 fix

I see that v2.1.61 added "Fixed concurrent writes corrupting config file on Windows" and v1.0.45 added atomic writes. However, this happened to me on a recent version (~2.1.62+), so the race condition may not be fully resolved — at least on Windows with multiple parallel sessions sharing the same ~/.claude/ directory. The 68 corrupted files in my backups speak for themselves.

Suggestion for the Claude Code team

cc @igorkofman @ant-kurt @felixrieseberg

The partial writes I found (43-157 bytes vs 22KB normal) suggest the atomic write mechanism may not be covering all write paths to .claude.json, or there's still a window where concurrent reads can hit a truncated state. Possible additional hardening:

  • Verify atomic writes cover every .claude.json write path (not just config saves)
  • Add advisory file locking (flock on Linux/Mac, LockFileEx on Windows) as a second layer
  • Consider a self-repair mechanism: if .claude.json fails to parse, automatically regenerate it from .credentials.json instead of prompting for login

This likely affects anyone running multiple Claude Code sessions in parallel, regardless of OS — consistent with reports from @dwymark (3-4 WSL2 sessions), @scrapebros (multiple machines), and others in this thread.

Prevention: use worktrees for parallel sessions

The official docs explicitly recommend git worktrees for parallel sessions:

"When working on multiple tasks at once, you need each Claude session to have its own copy of the codebase so changes don't collide."

After switching to worktrees, zero corruptions. Claude Code even has a built-in flag for this:

# Built-in worktree support (creates .claude/worktrees/<name>/)
claude --worktree feature-auth
claude --worktree bugfix-123

# Or manually
git worktree add .claude/worktrees/my-feature -b my-feature
cd .claude/worktrees/my-feature && claude

I also added an auto-sync rule so that after any git push from a worktree, the main repo and all other active worktrees rebase automatically. This prevents merge conflicts between parallel sessions.

TL;DR: If you're running multiple Claude Code sessions in parallel without worktrees, that's likely your trigger. The fix above repairs the damage, and worktrees prevent it from happening again.

ugoi · 4 months ago

I'm getting this with ssh and termius app

!image

Dunno if that's related but I also constantly need to authenticate my mcp servers with oauth like every day mcp auth expires.

tedzhao226 · 4 months ago

Fix for SSH/headless sessions on macOS

I spent a while digging into this — in my case it's SSH via Termius to a Mac mini.

The issue is that Claude Code stores OAuth tokens in macOS Keychain (keytar / SecItemCopyMatching). Over SSH, the keychain is either locked or can't show the ACL approval dialog, so auth silently fails. The OAuth tokens also expire every ~8 hours and the refresh write-back fails too.

The workaround: Claude Code checks for a CLAUDE_CODE_OAUTH_TOKEN env var before hitting the keychain. So you can skip keychain entirely.

  1. From a GUI terminal (not SSH), run claude setup-token — this gives you a long-lived token (~1 year)
  1. Save it somewhere with restricted perms:
echo 'export CLAUDE_CODE_OAUTH_TOKEN="sk-ant-oat01-..."' > ~/.claude-token
chmod 600 ~/.claude-token
  1. Source it in your shell rc:
# ~/.zshrc or ~/.bashrc
[[ -f "$HOME/.claude-token" ]] && source "$HOME/.claude-token"
  1. Make sure ~/.claude.json has "hasCompletedOnboarding": true or you'll get the welcome screen again.

Haven't had to re-auth since. @ugoi this might help with your Termius setup too.

jmaddington · 3 months ago

I also feel like I'm just constantly being nagged to login. I use CC across 3-5 machines daily, macOS and Linux, not to mention multiple docker images. This includes many long-running sessions that go overnight.

It is SO frustrating to wake up in the morning and find that I'm logged out in 3 different places, or even just be logging in constantly during the day -- _especially_ when auth is down as it frequently has been. This isn't a small deal to me. Anthropic has made CC a core part of my daily workflows.

renan-lopes-eso · 3 months ago

I'm also experiencing this, It always asks for login and when I click authorized it does not work most of the time, either the claude code gives an error or the authorize page says server error
This is only happening in my cachyos linux machine, in my windows machine this does not happen.
Claude account with subscription

arekm · 3 months ago

CLAUDE_CODE_OAUTH_TOKEN solution didn't work well for me (claude worked but claimed I don't have subscription, didn't show 1M context model etc). But in my case claude asked for relogin on local machine.

So now on MacOS I have such "security" wrapper (that wraps /usr/bin/security) in PATH (so claude cli picks it up first). That PATH is for claude only.

It blocks keychain access for claude (only that) and claude fallbacks to using file ~/.claude/.credentials.json.

That seems to do the trick. Few days without requiring to log in again.

````
#!/usr/bin/env python3
"""Wrapper for /usr/bin/security — blocks credential store access, allows rest."""
import os, subprocess, sys

LOG = "/var/folders/x3/mrlwpclh0000gn/T/ai-sbox-stub.ew5gyexq/security.log"
REAL = "/usr/bin/security"

def log(msg):
import datetime
ts = datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S")
with open(LOG, "a") as f:
f.write(f"{ts} [{os.getpid()}] {msg}\n")

def is_blocked_service(val):
"""Block any service in the Claude Code -credentials family."""
return val.startswith("Claude Code") and "-credentials" in val

def has_blocked_service(args):
it = iter(args)
for a in it:
if a == "-s":
if is_blocked_service(next(it, "")):
return True
return False

args = sys.argv[1:]
cmd = args[0] if args else ""

log(f"security {' '.join(args)}")

Block find/add/delete-generic-password targeting credentials store.

if cmd in ("find-generic-password", "add-generic-password", "delete-generic-password"):
if has_blocked_service(args):
log(f"BLOCKED: {cmd} with credentials service")
sys.exit(1)

Interactive mode (-i): read stdin, check, then replay to real binary.

if "-i" in args:
stdin_data = b""
if not sys.stdin.isatty():
stdin_data = sys.stdin.buffer.read()
text = stdin_data.decode("utf-8", errors="replace")
if is_blocked_service(text.split("-s ")[-1].split('"')[1] if "-s " in text else ""):
log(f"BLOCKED: -i stdin with credentials service")
sys.exit(1)
# Replay stdin to real binary — cannot execv after consuming stdin.
r = subprocess.run([REAL] + args, input=stdin_data)
sys.exit(r.returncode)

os.execv(REAL, [REAL] + args)

````

yarikoptic · 2 months ago

CLAUDE_CODE_OAUTH_TOKEN stopped working for me in my podman yolo environment and was always having that side-effect of not being fully considered 'subscription' one. It is quite ridiculous that at hundred(s) bucks a month service fee we have no user support here! From https://support.claude.com/en/articles/9015913-how-to-get-support

Pro and Max plans, Team and Enterprise plan Owners, and Console Admins
You have full access to:

  • All help documentation
  • Fin, our AI support bot
  • Further assistance from our Product Support team

Note: While we don't offer phone or live chat support, our Product Support team will gladly assist you through our support messenger.

so might be worth pursuing? (edit: chatted to Fin, he said that inquiry submitted to an agent and I will be contacted via email... I pointed to this issue in the dialog/details I accumulated/shared)

Einlanzerous · 1 month ago

fwiw, also seeing this, I don't hate myself so not on OSX, but sshing into my server and using it there I do see basically daily login requests (also fwiw seems like Claude Code will close with a broken pipe if left open for a while, tmux obvi doesn't have this issue, but just stands out as gemini cli can stay rock solid forever). I'll try the token fix, thanks for sharing.

prmichaelsen · 1 month ago

I'm seeing this as well now. https://github.com/anthropics/claude-code/issues/62354

It, without exaggeration, makes development impossible, which means I'm paying $200/mo for a fundamentally broken service.

Environment Info

Platform: linux
Terminal: vscode
Version: 2.1.150
Feedback ID: d8f6083a-0911-4fc0-882c-a9565a5e5e7c
canopatrick · 1 month ago

I'm also seeing this, and it's super annoying. Started maybe a week or two for me with no rhyme or reason.

Albermonte · 1 month ago

I found that my issue was a third party app called ClaudeBar, after uninstalling it, my session doesn't expire anymore

joaoolivati · 1 month ago

Environment

  • Claude Code version: 2.1.159
  • OS: macOS Darwin 24.6.0 (MacBook)
  • Auth mode: Claude.ai OAuth / Pro subscription
  • Shell: zsh
  • Install: CLI (terminal)

Behavior

Every new terminal session shows:

API Error: 401 Invalid authentication credentials
Please run /login

Running /login resolves the issue for that session, but the problem repeats on the next terminal session (typically the next day).

Root Cause Identified

Inspecting the keychain entry Claude Code-credentials via security find-generic-password -s "Claude Code-credentials" -g, the stored credential shows:

  • accessToken present and valid immediately after /login
  • expiresAt set to ~8 hours after login
  • refreshToken present in the stored credential

Despite the refreshToken being stored in the keychain, Claude Code does not automatically use it to renew the accessToken when it expires. On the next session start, it finds an expired accessToken and immediately throws 401 instead of attempting a refresh.

Expected Behavior

Claude Code should silently use the refreshToken to obtain a new accessToken on startup (or on first API call) when the stored accessToken is expired.

Workaround

None available for Pro subscribers (no API key included in Pro plan). Daily /login is currently the only option.

Related Issues

  • #54443 (OAuth refresh returns 400 — Linux/Max)
  • #60104 (sleep/wake 401 — macOS)
  • #12447 (OAuth token expiration disrupts autonomous workflows)
Marsssssssssssdsss · 1 month ago

@scrapebros The session token expires server-side but the client doesn't know when. Workaround: cache the session token to disk with a refresh heuristic — if it works, use it; if it fails, re-auth once. This replaces the "guess every 24h" logic with actual try-and-recover.

clinton-vanry · 1 month ago

This issue is occurring in Claude Code version v2.1.177, where users are required to log in multiple times throughout the day.

arsinoeii · 18 days ago

Still experiencing this on v2.1.195 (macOS, 27 June 2026).

Reproduction: Mid-session, Claude Code spontaneously shows "Not logged in - Please run /login". Running /login reports "Login successful" but immediately reverts to "Not logged in - Please run /login". This loops indefinitely — tried multiple times in a row with the same result. Session had been running for approximately 15 seconds before the first logout.

No concurrent sessions were running at the time. No SSH, no Docker — plain local terminal.

Feedback bundle submitted: cc-20260627-085331-566489

This is a year-old issue now with 20+ duplicate reports. The partial fixes in v2.1.81/117/121/126 have not resolved the core problem. Would appreciate visibility on whether a comprehensive fix for the OAuth token lifecycle is planned.

Drickon · 17 days ago

This looks like the same recurring auth-latch a lot of you are hitting: 401 "Invalid authentication credentials" / "Please run /login" that never clears until you restart. We've been chasing it on a headless fleet and have a precise characterization of what's actually happening. Short version: the token stays valid the whole time. We proved it by firing the same token externally and getting 200 at the exact instant the wedged instance got 401, so it's the running instance's session that gets rejected, not the credential, which is why nothing short of a restart fixes it.

TL;DR: this 401 tracks the running instance's session, not the token, and the same token succeeds externally at the same instant. We run several headless Claude Code instances (v2.1.195) authed with a single static sk-ant-oat01… env token (claude setup-token, no refresh token, no .credentials.json). They recurrently start getting 401 Invalid authentication credentials / "Please run /login", and then hard-latch and never self-recover until the process is restarted.

**The token is fine the whole time. The session is what's rejected. During a live wedge we fired raw POST /v1/messages with the exact same static token, in many shapes (minimal, agent-shaped, large cache-creation, streaming, 12 tools, metadata, resumed-style). All returned 200 at the same instant the wedged instance's own turns returned 401.** Same token, account, IP, model, request shape, yet 200 externally and 401 from inside the wedged process. The rejection is tied to that instance's long-lived server-side session/process identity.

It's a hard client-side latch on a still-valid token. Across 412 sessions / 153 distinct 401 events: zero self-recovered without a restart. Even after the upstream rejection window closes, the instance stays latched. We're already on v2.1.195 (includes the v2.1.117 reactive-401-refresh and v2.1.178 stale-cached-config fixes) and it still latches, consistent with the cause being session-identity-bound, not token-bound, so re-minting/refreshing can't help.

Token probes are structurally blind here. Any "is the token valid?" check shares the token but not the wedged session identity, so it reads 200 throughout and tells you nothing. Verify recovery by an observed non-401 turn, never by a probe.

This isn't unique to our setup: anthropics/claude-code #61912 independently captured the same token returning 200 on /oauth/hello and 401 on /v1/messages in the same second, unexpired.

Separate, distinct issue (don't conflate): in one ~7h outage, direct probes showed Opus 4.8 and Sonnet 4.6 returning 429 rate_limit_error (generic body, x-should-retry: true, no retry-after) while Haiku returned 200 on the same token. The 5h cap was ~10% used, had reset ~3h earlier, and the 429 persisted through >5h idle, so this is not a usage cap. A naive Haiku probe reads 200 and misreports this big-model-tier throttle as "token fine."

Real request_ids (all 401 authentication_failed, token valid throughout, for tracing):

req_011CcVDWWs8GPfDyX8R9LEfW   2026-06-28 01:52 CDT
req_011CcVDW3MetrtoQqLU2m8cn   2026-06-28 01:52 CDT
req_011CcUaNDekFKPWogaeZ9adT   2026-06-27 17:45 CDT
req_011Cc3X8oSfApMWRCs66taQw   2026-06-14 12:10 CDT

Workaround we run: a watchdog that detects the 401 in the instance's logs, restarts the wedged instance, and verifies recovery by an observed non-401 turn (never a token probe), with a quiet-window backoff so it doesn't restart-storm into a still-open upstream window.

The one ask: the client latch should not survive the upstream window closing (it does, on v2.1.195). A session-identity 401 needs the client to re-establish session state, not just refresh the token. At minimum, surface an actionable error instead of a dead "Please run /login."

Full forensic write-up: full forensic write-up