[BUG] Desktop SSH connections fail when ~/.ssh is an iCloud Drive symlink — spawned ssh/ssh-keygen can't read known_hosts or config
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?
The desktop app's "Add SSH connection" always fails with Host denied (verification failed) and:
"<host>" is not in ~/.ssh/known_hosts yet, or its host key has changed. If this is your first connection to it, run ssh to this host once in a terminal and accept the host key, then test again. If you have connected before and the machine was not reinstalled, do not connect.
Command-line ssh to the same host from the same Mac succeeds, and the host key is in ~/.ssh/known_hosts and current (verified by comparing fingerprints against /etc/ssh/ssh_host_*_key.pub read over an already-trusted session). Following the dialog's advice therefore changes nothing.
Entering an alias from ~/.ssh/config in the SSH Host field fails earlier, at getaddrinfo ENOTFOUND, even though the field's helper text offers "a host from ~/.ssh/config".
Root cause
On this machine ~/.ssh is a symlink into iCloud Drive (~/Library/Mobile Documents/com~apple~CloudDocs/...), a TCC-protected location, so one keystore can be shared between two Macs.
The app shells out to ssh -G and ssh-keygen -F. Those children get the correct HOME and resolve to /usr/bin/ssh and /usr/bin/ssh-keygen, but they do not inherit Claude.app's kTCCServiceFileProviderDomain grant, so ~/.ssh is effectively invisible to them. The app's own Node fs reads are unaffected, which is what makes this hard to diagnose.
Evidence (from ~/Library/Logs/Claude/ssh.log)
identityFiles: 5— realssh -G <host>returns 1 identity file for this host. 5 is exactly whatssh -F none -G <host>returns, i.e. the user config was never read.- An alias defined in
~/.ssh/configis logged asHost <alias> is not in known_hosts— the raw string was used as the hostname, sossh -Goutput was discarded. - The rejection is always the "lookup returned nothing" branch (
host is not in known_hosts), never the "presented key does not match" branch. No key comparison ever happens. keys: 1[ssh-rsa]— an identity file read in-process from that same iCloud-backed directory (the agent holds 3 keys, so this is the file from the dialog, not the agent).
Host key type is not involved: adding every key type the server offers, in any order, changes nothing, because the file is never read.
Related but distinct: #72735 reports the same error string caused by a genuine host key rotation.
What Should Happen?
Two things:
- The connection should succeed. The host key is present and current in
~/.ssh/known_hosts, and command-linesshaccepts it. Readingknown_hostsandssh_configin-process — the way identity files are already read — would remove the dependency on TCC grants that spawned OpenSSH binaries do not inherit.
- The error should distinguish "the known_hosts lookup could not run" from "the presented key does not match." The current message asserts the host is unknown or re-keyed and warns "do not connect", when in fact nothing was compared. Only a genuine mismatch warrants the MITM warning; as written, it sends users off to re-record a host key that is already correct, which cannot help.
Error Messages/Logs
~/Library/Logs/Claude/ssh.log (host/user redacted):
[info] [SSH2Connection] Resolved <user>@<host> -> <user>@<host>:22 (identityFiles: 5)
[warn] [SSH2Connection] Host <host> is not in known_hosts
[info] [SSH2Connection] Connecting to <user>@<host>:22 (agent: env:/var/run/com.apple.launchd.XXXXX/Listeners, keys: 1[ssh-rsa], proxy: false, keyboard: true)
[warn] [SSH2Connection] Rejecting host key for <host> - host is not in known_hosts
[error] [SSH2Connection] Connection error: Host denied (verification failed)
[error] [RemoteServerController] Connection failed (166ms, trigger: send_message, attempt 1): Host denied (verification failed)
[warn] [RemoteServerController] Auto-reconnect aborted: terminal error class "hostkey" (Host denied (verification failed))
With a ~/.ssh/config alias in the SSH Host field, the alias is never resolved:
[warn] [SSH2Connection] Host <alias> is not in known_hosts
UI, when an alias is entered:
Couldn't find the host "<alias>". Check the spelling in SSH Host, or connect to your VPN if it is an internal name.
getaddrinfo ENOTFOUND <alias>
Same shell, same user, same HOME - the lookups the app relies on all succeed:
$ ssh-keygen -F <host>
# Host <host> found: line 51
<host> ssh-ed25519 AAAAC3NzaC1lZDI1NTE5...
$ ssh -G <host> | grep -c '^identityfile'
1
$ ssh -F none -G <host> | grep -c '^identityfile'
5 # <- the number the app logs
$ ssh <alias>
<remote hostname> # alias resolves fine via ~/.ssh/config
Steps to Reproduce
On macOS, with ~/.ssh relocated into iCloud Drive (a common setup for sharing one keystore between two Macs):
- Move
~/.sshinto iCloud Drive and symlink it back:
````
mv ~/.ssh "$HOME/Library/Mobile Documents/com~apple~CloudDocs/ssh-store"
ln -s "$HOME/Library/Mobile Documents/com~apple~CloudDocs/ssh-store" ~/.ssh
- Confirm OpenSSH is happy from a terminal - both of these must succeed:
````
ssh <user>@<host> # connects
ssh-keygen -F <host> # prints the recorded host key
- In the desktop app, add an SSH connection: SSH Host
<user>@<host>, port empty, Identity File set to a key in~/.ssh. - Click Test connection.
Observed: Connection failed: Host key not trusted / Host denied (verification failed), with the dialog claiming the host is not in ~/.ssh/known_hosts or has been re-keyed.
- Open
~/Library/Logs/Claude/ssh.log. It showsHost <host> is not in known_hostsandidentityFiles: 5- the latter being the count you get only when~/.ssh/configis not read (ssh -F none -G).
Also reproducible in step 3 by entering a ~/.ssh/config alias instead of <user>@<host>: it fails at getaddrinfo ENOTFOUND because the alias is never resolved through the config.
A machine with a normal, local ~/.ssh does not reproduce this.
Claude Model
None
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.237 (Claude Code), in Claude desktop 1.34493.1
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
Environment
- Claude desktop 1.34493.1 / Claude Code 2.1.237
- macOS 26.5.2, Apple Silicon
- OpenSSH from
/usr/bin(bothsshandssh-keygenresolve there on the login-shell PATH)
Ruled out while diagnosing
- Missing or stale host key entries. All host key types the server offers were added, verified against
/etc/ssh/ssh_host_*_key.pubover an already-trusted session, and reordered; no effect. The file is never read. - Malformed
known_hosts. 63 lines, no CRs, no markers, no blank or short lines, onlyssh-ed25519/ecdsa-sha2-nistp256/ssh-rsa. - Wrong
HOMEin spawned children.ps -Ewwon a process the app spawned showsHOME=/Users/<user>. ssh-keygennot on PATH, or a slow/failing login-shell PATH probe. It resolves to/usr/bin/ssh-keygen, andzsh -lcreturns in ~25 ms.- TCC being denied to the app itself. Both
com.anthropic.claude-codeandcom.anthropic.claudefordesktopholdkTCCServiceFileProviderDomain(allowed), and the app reads an identity file from the same directory in-process. Only the spawned OpenSSH binaries are affected.
Workarounds
None that keep the setup intact. Moving config and known_hosts back to real local files outside iCloud Drive would fix it, at the cost of the shared keystore. Granting Full Disk Access to /usr/bin/ssh and /usr/bin/ssh-keygen may also work, but that is a broad grant to system binaries and I did not test it.
Note: this reproduces on both Macs sharing the keystore, so the app cannot SSH out from either.