[BUG] v2.0.14 macOS Keychain issue - OAuth authentication doesn't persist without security unlock-keychain each session

Resolved 💬 11 comments Opened Oct 11, 2025 by arwright Closed Jan 21, 2026

[UPDATE - This is NOT a service name mismatch]

See comments below regarding use of "security unlock-keychain ~/Library/Keychains/login.keychain-db" in each session to allow access to stored credentials from /login on macOS.

Original report follows:
----------------------------------------

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

OAuth login (/login) successfully stores credentials in macOS Keychain under service name "Claude Code-credentials", but Claude Code v2.0.14 startup attempts to read from "Claude Code" (without -credentials suffix). This service name mismatch causes authentication to fail on every new session.

Evidence:
bash

OAuth /login writes credentials here - this succeeds:

$ security find-generic-password -s "Claude Code-credentials" -w
{"claudeAiOauth":{"accessToken":"sk-ant-oat01-...","refreshToken":"..."}}

Claude Code startup reads from here - this fails:

$ security find-generic-password -s "Claude Code" -w
security: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.
Impact:

Authentication only works in the session where /login was executed
Every new terminal session requires re-authentication with "Invalid API key - Please run /login"
Affects both local terminal sessions AND remote SSH sessions
Makes Claude Code unusable without repeated logins

What Should Happen?

Claude Code should use consistent service names for both writing and reading credentials from macOS Keychain.
Fix options:

Option A: Update OAuth flow to write credentials to "Claude Code" instead of "Claude Code-credentials"
Option B: Update startup credential retrieval to read from "Claude Code-credentials" instead of "Claude Code"

Expected result: After running /login once, authentication should persist across all new terminal sessions without requiring the workaround or showing auth conflict warnings.

Error Messages/Logs

Debug logs showing Keychain lookup failure:
{"error":"Error: Command failed: security find-generic-password -a $USER -w -s \"Claude Code\"\nsecurity: SecKeychainSearchCopyNext: The specified item could not be found in the keychain."}

Terminal warning after applying workaround:
⚠️ Auth conflict: Both a token (claude.ai) and an API key (/login managed key) are set. This may lead to unexpected behavior.
   • Trying to use claude.ai? claude /logout
   • Trying to use /login managed key? claude /logout to sign out of claude.ai.

Keychain dump showing actual credential storage:
bash$ security dump-keychain | grep -i claude -A 5
    0x00000007 <blob>="Claude Code-credentials"
    0x00000008 <blob>=<NULL>
    "acct"<blob>="rsargent"
    "svce"<blob>="Claude Code-credentials"

Steps to Reproduce

1) Install Claude Code v2.0.14 (native installation)
2) Run claude
3) Execute /login command
4) Complete OAuth authentication in browser
5) Observe "Login successful" message
6) Exit Claude Code completely (exit or Ctrl+D)
7) Start a new Claude Code session: claude
8) Bug: See "Invalid API key - Please run /login" error
9) Verification: Run security find-generic-password -s "Claude Code" -w → fails
10) Verification: Run security find-generic-password -s "Claude Code-credentials" -w → succeeds (credentials exist)

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

Unknown

Claude Code Version

v2.0.14

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

Workaround (confirmed working):
bash# Run after every /login to sync credentials
CREDS=$(security find-generic-password -s "Claude Code-credentials" -w)
security add-generic-password -a "$USER" -s "Claude Code" -w "$CREDS"
Result: ✅ Authentication persists across sessions (warning shown but harmless)
Related Issues:

#5225 - Claude Code Login Authentication Not Persisting for Subscriber Users on remote SSH in MAC
#5244 - macOS OAuth authentication succeeds but auth token not persisted
#7358 - Claude Code SSH Authentication
#1222 - Authentication UI Warning Persists After Successful Login

Root Cause Analysis:
The inconsistency appears to be between:

Write path (OAuth flow): Uses service name "Claude Code-credentials"
Read path (Startup): Uses service name "Claude Code"

Both Keychain operations work correctly when using the proper service name, confirming this is purely a naming inconsistency rather than a permission or Keychain access issue.
Changelog Note:
v2.0.14 included "Reduce unnecessary logins" feature - this bug may be related to those authentication improvements.

View original on GitHub ↗

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