You type ssh user@your-vps, you know the key is right, and the server answers with Received disconnect from 203.0.113.10 port 22:2: Too many authentication failures. You haven't even been asked for a password. This one confuses a lot of people because nothing looks wrong on the server. Let's walk through why it happens and how to fix it for good.
Symptom
The full message usually looks like this:
Received disconnect from 203.0.113.10 port 22:2: Too many authentication failures
Disconnected from 203.0.113.10 port 22
user@203.0.113.10: Permission denied (publickey).
It tends to show up when you manage several servers, use a password manager that loads keys into an agent, or recently added a new key to your laptop. The login worked yesterday, and today it doesn't.
Cause: your client offers too many keys
When you connect, the SSH client doesn't just try the one key you're thinking of. It tries, in order: any keys loaded in ssh-agent, then keys named in IdentityFile lines, then default files like ~/.ssh/id_ed25519 and ~/.ssh/id_rsa. Each rejected key counts as one failed attempt.
The server limits this with MaxAuthTries in /etc/ssh/sshd_config. The default is 6. If your agent holds seven keys and the right one is the seventh, the server hangs up before your client ever offers it.
So the problem isn't a wrong key. It's the wrong order, or simply too many keys.
Step 1: See what your client is actually offering
Run the connection in verbose mode:
ssh -v user@203.0.113.10
Look for lines like Offering public key:. Count them. If you see six rejected offers followed by the disconnect, you've found the issue. You can also list what the agent holds:
ssh-add -l
Step 2: Fix it on your side (the right fix)
Option A: Force the one key you want
This is the quickest one-off:
ssh -o IdentitiesOnly=yes -i ~/.ssh/skyserver_vps user@203.0.113.10
IdentitiesOnly=yes tells the client to use only the key you pointed at with -i and ignore everything in the agent.
Option B: Make it permanent in ~/.ssh/config
Create a host block so you never think about it again:
Host myvps
HostName 203.0.113.10
User deploy
Port 22
IdentityFile ~/.ssh/skyserver_vps
IdentitiesOnly yes
Now ssh myvps offers exactly one key. Make sure the file permissions are tight, or SSH will quietly ignore it:
chmod 600 ~/.ssh/config ~/.ssh/skyserver_vps
Option C: Clean up the agent
If you've piled up old keys, remove them:
ssh-add -D # remove all identities from the agent
ssh-add ~/.ssh/skyserver_vps # add back only what you need
Step 3: Raise MaxAuthTries on the server (only if needed)
Sometimes you can't change the client, for example an automation tool or a teammate's setup. You can raise the server limit a little:
sudo nano /etc/ssh/sshd_config
# change or add:
MaxAuthTries 10
sudo sshd -t && sudo systemctl reload sshd
Always run sshd -t first. It validates the config, so a typo doesn't lock you out. Keep your current session open while you test a new one in a second terminal.
Raising MaxAuthTries is a workaround, not a cure. A higher limit gives password-guessing bots more tries per connection too. Fix the client first and keep the server at 3 to 6.
Quick reference
| Situation | Best fix |
|---|---|
| One server, one key | IdentitiesOnly yes in ~/.ssh/config |
| Many servers, many keys | One Host block per server with its own IdentityFile |
| Agent full of old keys | ssh-add -D, then re-add what you need |
| CI or automation you can't edit | Slightly higher MaxAuthTries, plus fail2ban |
| Still denied after one key offered | It's a different problem: check authorized_keys and permissions |
When it's not really "too many" failures
If ssh -v shows only one key offered and you still get denied, the cause is different. Check that the public key is in ~/.ssh/authorized_keys on the server, that ~/.ssh is 700 and authorized_keys is 600, and that the home directory isn't group-writable. Also confirm PubkeyAuthentication yes in sshd_config. Server logs help here:
sudo journalctl -u ssh -n 50 # Debian/Ubuntu
sudo tail -n 50 /var/log/secure # AlmaLinux/Rocky
Prevention
- Give each server (or group of servers) its own key and a matching Host block.
- Always set
IdentitiesOnly yeswhen you keep more than two or three keys. - Prune your agent now and then with
ssh-add -l. - Keep
MaxAuthTriesat a sensible value and run fail2ban, as covered in our SSH hardening guide. - Name keys clearly, like
skyserver_vpsandgithub_work, so you know what's what months later.
Frequently Asked Questions
Does this lock me out of the server for good?
No. The disconnect only ends that one connection. You can reconnect right away. If fail2ban is running and you've triggered it repeatedly, your IP may be temporarily banned, which is a separate issue.
Why did it start after I added a new key?
Adding a key to the agent pushes the total over the server's limit, or changes the order so the right key comes later. The server config didn't change; your client's offer list did.
Is it safe to set MaxAuthTries very high?
It isn't recommended. Each extra try helps brute-force bots. Prefer IdentitiesOnly on the client and keep the server limit low.
Does this affect Git over SSH too?
Yes. The same logic applies to GitHub or GitLab connections. A Host block with IdentitiesOnly for each service avoids offering the wrong key.
I'm on Windows. Where's the config file?
It's at C:\Users\YourName\.ssh\config when you use the built-in OpenSSH client. PuTTY users can pick the private key under Connection, SSH, Auth, and clear Pageant if it holds too many keys.
