Skip to content
Home » Common SSH Errors on macOS and What They Actually Mean

Common SSH Errors on macOS and What They Actually Mean

Three real SSH error lines stacked: Permission denied listing publickey, password and keyboard-interactive; Received disconnect port 22:2 Too many authentication failures; and the WARNING REMOTE HOST IDENTIFICATION HAS CHANGED banner

SSH errors are unusually good at pointing at the wrong thing. “Permission denied” reads like a password problem when it is usually a key problem, and “Too many authentication failures” sounds like you typed something wrong repeatedly when you have not typed anything at all.

Four of them cover most of what you will hit on a Mac. The outputs below were reproduced on macOS 26.5.2 running OpenSSH_10.2p1, LibreSSL 3.3.6, against a local sshd, using isolated test files rather than the real ~/.ssh.

Permission denied (publickey)

$ ssh osxhub@localhost
osxhub@localhost: Permission denied (publickey,password,keyboard-interactive).

The user name is replaced; the rest is as printed. The part in brackets is the useful bit, and it is easy to misread: it is not a list of what failed, it is the list of methods the server is willing to accept. Here the server would take a key, a password, or keyboard-interactive, and none of what the client offered satisfied any of them.

When the brackets contain only (publickey), the server has passwords disabled entirely — which is normal for cloud hosts and means no amount of getting the password right will help. Work through this order:

  • Is your key even loaded? ssh-add -l prints The agent has no identities. when nothing is loaded, which is the single most common cause after a reboot.
  • Is your public key on the server? It has to be a line in that account’s ~/.ssh/authorized_keys. Copying the private key around instead is a common and useless move.
  • Are the permissions right on the server? sshd refuses keys silently if ~/.ssh is group-writable. chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys, on the remote side.
  • Are you connecting as the right user? ssh server uses your Mac’s local user name, which is rarely the remote one.

If the connection does not even get far enough to be refused, the problem is the network rather than authentication — check whether port 22 is reachable before debugging keys.

Too many authentication failures

Received disconnect from ::1 port 22:2: Too many authentication failures

This one is almost never about you. It is about your agent having collected more keys than the server will let a single connection try, and running ssh -v shows exactly that happening:

debug1: Offering public key: k1 ED25519 SHA256:JCg5LfWL... agent
debug1: Offering public key: k2 ED25519 SHA256:2of6z979... agent
debug1: Offering public key: k3 ED25519 SHA256:Eoa2MMfb... agent
debug1: Offering public key: k4 ED25519 SHA256:mQy8Dq/G... agent
debug1: Offering public key: k5 ED25519 SHA256:rbmK1ctS... agent
debug1: Offering public key: k6 ED25519 SHA256:5rl0YgZq... agent
Received disconnect from ::1 port 22:2: Too many authentication failures

Fingerprints are truncated for width; the sequence is as printed. Fourteen keys were loaded in the agent for that test. The client offered them one at a time, the server counted each one as a failed attempt, and on the seventh it hung up — before ever reaching the key that would have worked, if one had been there.

The number is the server’s MaxAuthTries, which defaults to 6. So the cause is entirely on your side: an agent holding seven or more identities cannot reliably connect to a default-configured server, no matter which of those keys is the right one.

The fix is to stop offering everything. IdentitiesOnly=yes tells ssh to use only the key you named:

$ ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 osxhub@server
debug1: Offering public key: ~/.ssh/id_ed25519 ED25519 SHA256:JCg5LfWL... explicit agent

The path is shortened here; the trailing explicit agent is as printed and is the point — one offer instead of fourteen, and the disconnect never happens. ssh-add -D clears the agent entirely if you would rather start over.

Host identification has changed

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:CEQWNbKbAVI5TirBM1rRV2518Jxp5g1E0/9S6kW36TE.
Please contact your system administrator.
Add correct host key in ~/.ssh/known_hosts to get rid of this message.
Offending ED25519 key in ~/.ssh/known_hosts:1
Password authentication is disabled to avoid man-in-the-middle attacks.

Paths are shortened to ~/.ssh/known_hosts; the rest is as printed. Two lines in that wall of text are the ones to read.

Offending ED25519 key in ~/.ssh/known_hosts:1 gives you the file and the line number, so the fix is surgical rather than nuclear. ssh-keygen -R hostname removes exactly that entry and keeps every other host you have ever connected to, which deleting the whole file does not.

Password authentication is disabled to avoid man-in-the-middle attacks explains why the connection will not even let you fall back to typing a password — ssh refuses to hand a credential to a host it cannot identify.

Before removing anything, decide whether the change is expected. A server that was rebuilt, a VM restored from a snapshot, or a container that regenerates host keys will all produce this legitimately. The same warning appearing on a host you have not touched, especially over a network you do not control, is the case the message was written for — and clearing it without asking is exactly the wrong move.

Using -v to see what actually happened

Every error above becomes obvious with one flag. ssh -v prints the negotiation as it happens: which keys were offered and in what order, which config files were read, and what the server replied. Two more levels exist (-vv, -vvv), but the first is usually enough — the Offering public key lines alone answer most “why is it not using my key” questions.

One line worth looking for is Authentications that can continue:, which lists what the server will still accept at that point in the exchange. When it stops including publickey, your keys are out of the running and anything further you try with them is wasted effort.

Making the fix permanent

Passing -o IdentitiesOnly=yes -i somekey every time gets old. ~/.ssh/config holds it per host:

Host myserver
    HostName server.example.com
    User osxhub
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

After that, ssh myserver offers one key to that host and nothing else. Set the file’s permissions with chmod 600 ~/.ssh/config — ssh ignores a config file that other accounts can write to, and does so without saying why.

Two macOS-specific options belong in there as well if you use a passphrase: UseKeychain yes stores it in the login keychain, and AddKeysToAgent yes loads the key into the agent on first use. Neither exists on Linux, which is why they are missing from most SSH guides — and why “I have to type my passphrase every single time” is such a common complaint on Macs specifically.

Leave a Reply

Your email address will not be published. Required fields are marked *