OAuth refresh token not used when credentials are copied to remote/headless machines

Resolved 💬 5 comments Opened Jan 29, 2026 by khaledfouad0 Closed Mar 28, 2026

Bug Description

When copying ~/.claude/.credentials.json from an authenticated machine to a remote/headless machine, Claude Code throws a 401 authentication_error ("OAuth token has expired") instead of using the refreshToken present in the credentials file to obtain a new access token.

Steps to Reproduce

  1. Authenticate Claude Code on a local workstation via claude login (Max subscription, OAuth flow)
  2. Copy ~/.claude/.credentials.json to a remote headless machine (e.g., via scp)
  3. Run claude on the remote machine after the accessToken has expired

Expected Behavior

Claude Code should detect the expired accessToken, use the refreshToken to obtain a new access token, and continue normally — the same way it does on the original machine.

Actual Behavior

API Error: 401 {"type":"error","error":{"type":"authentication_error","message":"OAuth token has expired. Please obtain a new token or refresh your existing token."},"request_id":"req_011CXc8h3VFKY9jGum2N2rTZ"}

Credentials File Structure

The .credentials.json contains all necessary fields for a refresh:

{
  "claudeAiOauth": {
    "accessToken": "...",
    "refreshToken": "...",
    "expiresAt": ...,
    "scopes": [...],
    "subscriptionType": "max",
    "rateLimitTier": "..."
  }
}

The refreshToken is present but is not being used when the accessToken expires.

Use Case

Managing multiple headless Linux machines (Proxmox LXCs, Incus containers) where browser-based claude login is not practical. These machines are on a Tailnet and the intended workflow is to authenticate once on a workstation and distribute credentials to headless nodes. The copy-paste authorization code flow on headless machines is unreliable.

Environment

  • Source machine: Windows 11, Claude Code (Max subscription, OAuth)
  • Target machines: Headless Linux (Debian/Ubuntu LXCs and VMs)
  • Network: Tailscale mesh
  • Claude Code version: Latest (as of Jan 2026)

View original on GitHub ↗

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