Multiple concurrent CLI sessions cause auth failure on token refresh (race condition)

Resolved 💬 3 comments Opened Apr 15, 2026 by coolbossov Closed Apr 19, 2026

Description

When running multiple concurrent Claude Code CLI sessions (4-7+), all sessions simultaneously lose authentication when the OAuth access token expires (~8 hours). This forces a full re-login across every session.

Environment

  • OS: macOS 15 (Darwin 25.4.0)
  • Claude Code version: 2.1.109
  • Auth method: claude.ai OAuth (.credentials.json plaintext fallback)
  • Subscription: Claude Max
  • Concurrent sessions: 4-7 interactive CLI sessions + desktop bridge + remote-control

Steps to Reproduce

  1. Log in to Claude Code CLI (claude auth login)
  2. Open 4+ concurrent CLI sessions (e.g., multiple terminal tabs or SSH sessions)
  3. Wait for the OAuth access token to expire (~8 hours)
  4. All sessions simultaneously fail with a login prompt

Expected Behavior

Token refresh should be coordinated so that only one session refreshes the token, and all other sessions pick up the new credentials from .credentials.json.

Actual Behavior

Multiple sessions race to refresh the expired access token simultaneously. If the OAuth server uses rotating refresh tokens:

  • The first session to complete refresh succeeds and writes new tokens to .credentials.json
  • All other sessions attempt to refresh with the now-invalidated old refresh token
  • Those sessions fail and show a /login prompt
  • Result: all sessions except one are logged out simultaneously

Root Cause Analysis

All CLI sessions share a single ~/.claude/.credentials.json file with one refresh token. There is no file-locking or coordination mechanism to prevent concurrent refresh attempts. With rotating refresh tokens, only one refresh can succeed — the rest invalidate.

This is especially problematic for:

  • Users running multiple terminal sessions
  • SSH connections (no browser fallback for re-auth)
  • Sessions bridged from the desktop app

Suggested Fix

  • File-lock-based refresh coordination: Only one process performs the refresh, others wait and read the updated credentials
  • Grace period for old refresh tokens: Accept the previous refresh token for a short window after rotation
  • Per-session token management: Each CLI session maintains its own OAuth tokens

Additional Context

  • CLAUDE_CODE_OAUTH_TOKEN (from claude setup-token) returns 401 "OAuth authentication is currently not supported" — this headless auth path appears broken as well
  • Running claude setup-token may also revoke the existing refresh token server-side, causing all active sessions to fail once their access token expires

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗