The message
Received disconnect from 203.0.113.10 port 22:2: Too many authentication failures
Disconnected from 203.0.113.10 port 22
On the server, the log says:
maximum authentication attempts exceeded for user from 203.0.113.20 port 47120 ssh2 [preauth]
Often you were never asked for a password. In our test, an account with a working password failed with this message before any prompt, because the keys used up all the attempts first.
Check the cause
Count the keys in your agent:
ssh-add -l
Then see what is really offered:
ssh -v user@server 2>&1 | grep -E 'Offering|Too many'
debug1: Offering public key: key1 ED25519 SHA256:...
debug1: Offering public key: key2 ED25519 SHA256:...
debug1: Offering public key: key3 ED25519 SHA256:...
debug1: Offering public key: key4 ED25519 SHA256:...
debug1: Offering public key: key5 ED25519 SHA256:...
debug1: Offering public key: key6 ED25519 SHA256:...
Received disconnect from 203.0.113.10 port 22:2: Too many authentication failures
Each key the server does not accept counts as one failure, and the limit is MaxAuthTries, 6 by default. In our test the sixth key still got its turn: with the right key in sixth place the login worked, and with six wrong keys ahead of it the login failed. A server with a lower limit fails sooner.
The fix: tell ssh which key to use
For one attempt:
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_server user@server
To make it permanent, add this to ~/.ssh/config:
Host server
HostName 203.0.113.10
User user
IdentityFile ~/.ssh/id_ed25519_server
IdentitiesOnly yes
-i alone is not enough. We tried it: without IdentitiesOnly, the agent's keys still went first, and the same error came back. IdentitiesOnly yes is what limits ssh to the keys you named.
More per-host settings are in these ssh config file examples.
If the key exists only in the agent
IdentityFile can point to the public key file. ssh then uses that file to choose the key, and the agent does the signing:
Host server
IdentityFile ~/.ssh/id_ed25519_server.pub
IdentitiesOnly yes
If you log in with a password
Keys only get in the way here, so turn them off for this login:
ssh -o PubkeyAuthentication=no user@server
In a config file, this is PubkeyAuthentication no in the host's block.
Other options
Keep fewer keys in the agent
ssh-add -l # list
ssh-add -d ~/.ssh/old_key # remove one
ssh-add -D # remove all
This removes keys from the agent only and leaves the files alone. If you use a separate key for each server, the list grows quickly, so the config above is the lasting answer.
Skip the agent for one host
Host server
IdentityAgent none
IdentityFile ~/.ssh/id_ed25519_server
This also works, but you type the key's passphrase every time if it has one.
Setting IdentitiesOnly for all hosts
You can put IdentitiesOnly yes under Host *. With no IdentityFile for a host, ssh tries the default files such as ~/.ssh/id_ed25519, and it ignores other keys in the agent. So hosts that relied on one of those other keys need their own IdentityFile line.
Do not raise MaxAuthTries for this
You can raise the limit on a server you control, but the cause is on the client. Every other server you connect to keeps its limit, and a higher limit gives anyone guessing more attempts for each connection.
Repeated failures can get you banned
If the server runs fail2ban, each disconnect like this can count against your address. In our test, one such disconnect added one failure to the sshd jail. If the error turns into Connection refused after a few tries, you may be banned. See fail2ban for SSH.
Questions
What is the default MaxAuthTries?
6. Each key the server rejects counts as one attempt, so an agent with many keys can use them up before the right one.
Why does ssh -i not fix it?
Without IdentitiesOnly yes, ssh still offers the agent's keys before the one named with -i.
How do I see which keys ssh offers?
Run ssh -v user@server and look for the Offering public key lines.
Sources
- ssh_config(5), IdentitiesOnly and IdentityFile
- sshd_config(5), MaxAuthTries
- ssh-add(1), OpenBSD manual