claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

Authentication UI Warning Persists After Successful Login

Open bjcoombs opened this issue 8 months ago • 2 comments

Bug Description Title: Claude Code CLI shows "Missing API key · Run /login" despite functional authentication

Description: While using Claude Code via SSH, I'm seeing a persistent message "Missing API key · Run /login" in the UI next to where I type messages. However, Claude Code is fully functional and responds to my queries correctly, suggesting that authentication is actually working properly.

Steps to reproduce:

  1. Start Claude Code via SSH
  2. Successfully authenticate via browser flow (copy URL to Safari, copy response code back)
  3. Successfully interact with Claude (messages are sent/received correctly)
  4. Notice the "Missing API key · Run /login" message remains visible in the UI

Expected behavior: Once successfully authenticated, the warning message should disappear.

Actual behavior: The warning message persists despite successful authentication and fully functional operation.

Environment details:

  • Claude Code CLI: Latest version
  • Operating system: macOS latest version
  • Connection method: SSH from Prompt 3 on iPad to Mac via local WiFi tunnel
  • Authentication method: Browser flow authentication (copy URL to Safari, copy response code back)
  • Subscription: Claude Max plan

Additional information:

  • Using Prompt 3 app on iPad to connect to Mac
  • Both devices on same local WiFi network
  • SSH tunnel established between iPad and Mac
  • Fully functional despite the persistent error message
  • The authentication flow completed successfully

Environment Info

  • Platform: macos
  • Terminal: ssh-session
  • Version: 0.2.124
  • Feedback ID: a5c6a2a6-3ec1-4d1b-a669-179a71cecdc5

Errors

[{"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.\n\n    at genericNodeError (node:internal/errors:983:15)\n    at wrappedFn (node:internal/errors:537:14)\n    at checkExecSyncError (node:child_process:882:11)\n    at execSync (node:child_process:954:15)\n    at KW (file:///Users/ben/.nvm/versions/node/v22.12.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:605:3513)\n    at file:///Users/ben/.nvm/versions/node/v22.12.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:535:15359\n    at D (file:///Users/ben/.nvm/versions/node/v22.12.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:493:13295)\n    at aN1 (file:///Users/ben/.nvm/versions/node/v22.12.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:535:14608)\n    at qB (file:///Users/ben/.nvm/versions/node/v22.12.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:535:14225)\n    at $J1 (file:///Users/ben/.nvm/versions/node/v22.12.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:1460:1005)","timestamp":"2025-05-21T11:52:14.944Z"},{"error":"Error: Could not resolve authentication method. Expected either apiKey or authToken to be set. Or for one of the \"X-Api-Key\" or \"Authorization\" headers to be explicitly omitted\n    at file:///Users/ben/.nvm/versions/node/v22.12.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:675:22923","timestamp":"2025-05-21T11:52:15.088Z"},{"error":"RangeError [ERR_CHILD_PROCESS_STDIO_MAXBUFFER]: stdout maxBuffer length exceeded\n    at Socket.onChildStdout (node:child_process:481:14)\n    at Socket.emit (node:events:524:28)\n    at Socket.emit (node:domain:489:12)\n    at addChunk (node:internal/streams/readable:561:12)\n    at readableAddChunkPushByteMode (node:internal/streams/readable:512:3)\n    at Readable.push (node:internal/streams/readable:392:5)\n    at Pipe.onStreamRead (node:internal/stream_base_commons:189:23)","timestamp":"2025-05-21T11:52:15.790Z"},{"error":"Error: Command failed: security delete-generic-password -a $USER -s \"Claude Code\"\nsecurity: SecKeychainSearchCopyNext: The specified item could not be found in the keychain.\n\n    at genericNodeError (node:internal/errors:983:15)\n    at wrappedFn (node:internal/errors:537:14)\n    at checkExecSyncError (node:child_process:882:11)\n    at execSync (node:child_process:954:15)\n    at KW (file:///Users/ben/.nvm/versions/node/v22.12.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:605:3513)\n    at eR0 (file:///Users/ben/.nvm/versions/node/v22.12.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:535:16418)\n    at tR0 (file:///Users/ben/.nvm/versions/node/v22.12.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:535:16302)\n    at li1 (file:///Users/ben/.nvm/versions/node/v22.12.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:2035:2555)\n    at ni1.startOAuthFlow (file:///Users/ben/.nvm/versions/node/v22.12.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:2035:3744)\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)","timestamp":"2025-05-21T11:53:11.703Z"},{"error":"Error: Command failed: security find-generic-password -a $USER -w -s \"Claude Code\"\nsecurity: SecKeychainSearchCopyNext: The specified item could not be found in 

Note: Error logs were truncated.

bjcoombs avatar May 22 '25 14:05 bjcoombs

Hi there,

Thank you for the detailed and well-documented bug report! Your description of the issue is perfectly clear.

This is a known behavior when using applications that rely on the macOS Keychain over an SSH session. You are correct that the application is fully functional because you've successfully authenticated through the browser flow. The persistent "Missing API key" message is a UI bug stemming from how SSH sessions interact with the Keychain.

The Root Cause

When you log into your Mac graphically, your login.keychain is automatically unlocked. However, for security reasons, a new SSH session does not have access to this unlocked keychain. Therefore, while the core functionality of Claude Code works using a session token from your browser authentication, the UI component that checks for the stored API key in the keychain fails, causing the warning message to remain visible.

The Solution: Manually Unlock Keychain

To resolve this and make the warning message disappear, you can manually unlock your login keychain within your SSH session. Here are the steps:

  1. Connect to your Mac via SSH as you normally do.

    ssh your_username@your_mac_address
    
  2. After logging in, run the following command in your SSH terminal. This will unlock the keychain for your current session.

    security unlock-keychain ~/Library/Keychains/login.keychain-db
    
  3. The terminal will prompt you for a password. Enter your Mac user login password (the same one you use to log into your computer).

After you enter the password, your keychain will be unlocked for the remainder of the SSH session. When you now start claude, it will be able to access the API key stored in the keychain, and the "Missing API key" warning should no longer be displayed.

For a More Permanent Fix (Optional)

If you SSH into this machine frequently, you can automate the unlock process by adding the command to your shell's startup script.

  1. In your SSH session, open your shell's configuration file (e.g., ~/.zshrc for Zsh, or ~/.bash_profile for Bash).

    # For Zsh (default on modern macOS)
    nano ~/.zshrc
    
  2. Add the following lines to the end of the file. This script checks if you are in an SSH session and, if so, runs the unlock command.

    if [ -n "$SSH_CONNECTION" ]; then
      security unlock-keychain ~/Library/Keychains/login.keychain-db
    fi
    
  3. Save the file and exit the editor.

Now, every time you start a new SSH session, you will be prompted for your keychain password right away, and all applications will have the access they need for the entire session.

Hope this helps clarify the issue and provides a solid workaround!

lijianwei89 avatar Jun 27 '25 15:06 lijianwei89

Updata:if [ -n "$SSH_CONNECTION" ]; then security unlock-keychain ~/Library/Keychains/login.keychain-db fi will import a new claude code bug

lijianwei89 avatar Jun 27 '25 15:06 lijianwei89

2. Add the following lines to the end of the file. This script checks if you are in an SSH session and, if so, runs the unlock command.
   if [ -n "$SSH_CONNECTION" ]; then
     security unlock-keychain ~/Library/Keychains/login.keychain-db
   fi

I use zsh. I added the above script to my .zprofile, so that it will only run in login shells.

Upon running Claude CLI I found that it is actually creating a login shell itself, which caused this to display:

Image

It also seemed to cause problems with the CLI input; many of my keystrokes would not register.

So, I updated the script like this:

# Unlock Keychain on login
if [ -n "$SSH_CONNECTION" ] && [ -z "$KEYCHAIN_UNLOCKED" ]; then
  security unlock-keychain ~/Library/Keychains/login.keychain-db
  export KEYCHAIN_UNLOCKED=true
fi

So far this seems to have resolved the issue. I get asked to unlock the Keychain once when I SSH in, and Claude CLI is functioning normally again.

I'm a little concerned about whether the Keychain session will timeout, and where that will leave my active tmux sessions. I also don't think Claude should be running a login shell in principle - but I imagine they wanted to make sure all shell configuration is definitely loaded.

ETA: I have been using Claude Code over SSH to a Macbook Pro for almost a month (when I started using CC) without this keychain issue. It just popped up yesterday. Did they recently add code to have the CLI use the keychain? Personally I would like to be able to disable that via config to be able to avoid the above workaround.

cwc avatar Aug 07 '25 14:08 cwc

@bcherny No update on this? I still have to unistall and install again every day.

titofebus avatar Aug 10 '25 21:08 titofebus

Unlock Keychain on login

if [ -n "$SSH_CONNECTION" ] && [ -z "$KEYCHAIN_UNLOCKED" ]; then security unlock-keychain ~/Library/Keychains/login.keychain-db export KEYCHAIN_UNLOCKED=true fi


ETA: I have been using Claude Code over SSH to a Macbook Pro for almost a month (when I started using CC) without this keychain issue. It just popped up yesterday. Did they recently add code to have the CLI use the keychain? Personally I would like to be able to disable that via config to be able to avoid the above workaround.

Thanks man!

gerfru avatar Aug 11 '25 06:08 gerfru

This probably bad in terms of security but saved me lot of time:

# use vs code (or derived) to put password into ~/.local/passwd, then add this block into your .zshrc
# may need less conditional check if you don't share .zshrc across multiple *nix systems
if [ -n "$SSH_CONNECTION" ] && [ -f "$HOME/.local/passwd" ] && [ -f "$HOME/Library/Keychains/login.keychain-db" ]; then
  security unlock-keychain -p "$(cat ~/.local/passwd)" ~/Library/Keychains/login.keychain-db
fi

ducmthai avatar Aug 14 '25 01:08 ducmthai

Any updates on this? the fixes above aren't working for me

nkolly avatar Aug 14 '25 14:08 nkolly

2. Add the following lines to the end of the file. This script checks if you are in an SSH session and, if so, runs the unlock command.
   if [ -n "$SSH_CONNECTION" ]; then
     security unlock-keychain ~/Library/Keychains/login.keychain-db
   fi

I use zsh. I added the above script to my .zprofile, so that it will only run in login shells.

Upon running Claude CLI I found that it is actually creating a login shell itself, which caused this to display:

Image It also seemed to cause problems with the CLI input; many of my keystrokes would not register.

So, I updated the script like this:

# Unlock Keychain on login
if [ -n "$SSH_CONNECTION" ] && [ -z "$KEYCHAIN_UNLOCKED" ]; then
  security unlock-keychain ~/Library/Keychains/login.keychain-db
  export KEYCHAIN_UNLOCKED=true
fi

So far this seems to have resolved the issue. I get asked to unlock the Keychain once when I SSH in, and Claude CLI is functioning normally again.

I'm a little concerned about whether the Keychain session will timeout, and where that will leave my active tmux sessions. I also don't think Claude should be running a login shell in principle - but I imagine they wanted to make sure all shell configuration is definitely loaded.

ETA: I have been using Claude Code over SSH to a Macbook Pro for almost a month (when I started using CC) without this keychain issue. It just popped up yesterday. Did they recently add code to have the CLI use the keychain? Personally I would like to be able to disable that via config to be able to avoid the above workaround.

This worked for me, thanks. I'm trying to get a iphone to mbp setup, only thing annoying about this is having to enter a password every time I open up my terminal app on my iphone (i know there's mosh, but it isn't working well for finger scroll atm but maybe need to put some time into configuring it).

pthieu avatar Aug 15 '25 03:08 pthieu

Still encountering this after trying the many different solutions posted here in other issues.

Claude Code v1.0.84

allenthich avatar Aug 19 '25 13:08 allenthich

I could not get any of the above workarounds to work.

I did finally after several hours end up with something that worked for me, however:

  1. Uninstalled all versions of claude (npm and native)
  2. Exit ssh, relogin to ssh
  3. security unlock-keychain ~/Library/Keychains/login.keychain-db
  4. npm install -g @anthropic-ai/[email protected]
  5. claude config set -g autoUpdates disable
  6. claude
  7. Do the /login flow (yea! it works!)
  8. run /migrate-installer inside claude (which also updates to latest)
  9. (this terminates claude after it is done)
  10. claude

Somehow this got my tokens in the right state and it works, even when I exit and ssh in again.

jensenharris avatar Aug 21 '25 04:08 jensenharris

the solution here doesn't seem to work anymore

domino14 avatar Aug 29 '25 16:08 domino14

So this is as recent as yesterday, is there really no fix for this?

Zach-Self avatar Aug 30 '25 20:08 Zach-Self

So this is as recent as yesterday, is there really no fix for this?

I fixed it by doing the thing above your comment, the Claude auto migrate thing along with the shell helper to unlock your keychain. Note that if you put in your keychain password wrong there is no error message.

domino14 avatar Aug 30 '25 20:08 domino14

I could not get any of the above workarounds to work.

I did finally after several hours end up with something that worked for me, however:

1. Uninstalled all versions of claude (npm and native)

2. Exit ssh, relogin to ssh

3. security unlock-keychain ~/Library/Keychains/login.keychain-db

4. npm install -g @anthropic-ai/[email protected]

5. claude config set -g autoUpdates disable

6. claude

7. Do the /login flow (yea! it works!)

8. run /migrate-installer inside claude (which also updates to latest)

9. (this terminates claude after it is done)

10. claude

Somehow this got my tokens in the right state and it works, even when I exit and ssh in again.

This worked for me.

cjfreeze avatar Sep 18 '25 19:09 cjfreeze