You just set up SSH keys, closed your only working session, and now every connection attempt throws "Permission denied (publickey)" with no password prompt to fall back on. It's one of the most common ways people lock themselves out of a VPS — and one of the fastest to fix once you know which of the usual suspects is causing it.
Symptom: no password prompt, just a flat refusal
The error looks the same no matter the cause:
root@203.0.113.10: Permission denied (publickey).A few things usually come with it:
- SSH doesn't even ask for a password — it just refuses immediately.
- It started right after you generated a new key pair, ran a hardening script, or rebuilt the server.
- It works from one machine but not another (your laptop connects fine, your new machine or CI runner doesn't).
- WinSCP, FileZilla, or a GUI SFTP client shows the same error even though the terminal "used to work."
This is a client-vs-server key mismatch, not a broken server — SSH is telling you the specific public key you offered isn't one the server will accept, or it can't trust the copy sitting in authorized_keys.
Quick diagnostic: run this first
Before touching any config, run a verbose connection and read the last ten lines — it almost always names the actual problem instead of leaving you guessing:
ssh -vvv user@your-server-ipWatch for three things in the output: which key files it tried under Offering public key, whether the server responds with Authentications that can continue: publickey (meaning your key just wasn't accepted) versus a connection that never got that far (a network or firewall issue, which is a different problem entirely), and the exact username being used to connect.
Cause 0: you're connecting as the wrong user
This causes more lockouts than anything else on this list, and it's easy to miss because the error looks identical to a genuine key problem. Cloud VPS images frequently don't provision root for SSH at all — Ubuntu images use ubuntu, some AlmaLinux images use a custom sudo user, and your key may only have been added to that account, not root.
ssh -i ~/.ssh/id_ed25519 ubuntu@your-server-ipIf you provisioned the server yourself and only remember setting up one user, check /root/.ssh/authorized_keys against /home/<user>/.ssh/authorized_keys from the console to see which one actually has your key.
Cause 1: you're offering the wrong key
If you have more than one SSH key on your machine, the client tries them in order until the server runs out of patience (MaxAuthTries, usually 6). On a server with several keys registered, or a client with several keys stored, the right key sometimes never gets offered before the connection is dropped.
Check what's actually being sent with verbose mode:
ssh -v user@your-server-ipLook for lines like Offering public key: /home/you/.ssh/id_rsa. If it's offering the wrong file, force the right one and stop it from trying others first:
ssh -i ~/.ssh/id_ed25519_getwebup -o IdentitiesOnly=yes user@your-server-ipCause 2: the public key isn't actually in authorized_keys
The most common mistake: pasting the private key into authorized_keys instead of the public one, or a copy-paste that wrapped the line and broke it into two. A valid entry is one unbroken line starting with ssh-ed25519 or ssh-rsa.
If you still have any working access — console, a second key, or root password — check the file directly:
cat ~/.ssh/authorized_keysCompare it character-for-character against your local public key (cat ~/.ssh/id_ed25519.pub). Re-add it cleanly with ssh-copy-id instead of pasting by hand next time:
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@your-server-ipCause 3: permissions on .ssh are too open
OpenSSH silently refuses to use authorized_keys if the permissions on the folder or file are looser than it expects — this is a security feature, not a bug, but it produces the exact same error with zero explanation. It won't warn you; it just falls through to "Permission denied."
| Path | Required permission | Fix command |
|---|---|---|
| Home directory | not group/world-writable | chmod 755 /home/user |
| ~/.ssh | 700 | chmod 700 ~/.ssh |
| ~/.ssh/authorized_keys | 600 | chmod 600 ~/.ssh/authorized_keys |
| Ownership | the login user, not root | chown -R user:user ~/.ssh |
Run all four in sequence for the affected user, then try connecting again before touching anything else.
Cause 4: SELinux is blocking it (AlmaLinux, RHEL, Rocky)
On SELinux-enforcing distros, moving or recreating authorized_keys outside the normal tools can leave it with the wrong security context, which SSH treats the same as a permissions problem. Check and fix it with:
ls -Z ~/.ssh/authorized_keys
restorecon -Rv ~/.sshIf the context printed by ls -Z doesn't say ssh_home_t, restorecon resets it to what SELinux expects and the key starts working immediately.
Cause 5: sshd_config is set up to reject it server-side
If you're fully locked out (no working key, no password fallback), you'll need console access to fix this — from your Getwebup VPS panel, open the VNC/console tab and log in as if you were sitting at the physical machine. From there, check /etc/ssh/sshd_config for:
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
If PubkeyAuthentication is set to no, or AuthorizedKeysFile points somewhere your key isn't, fix the line and reload:
systemctl restart sshdTest the fix from a second terminal window before closing the console session — if it's still broken, you want a way back in.
Prevention: don't let this happen mid-hardening
- Never close your only working session after adding a new key or disabling password auth. Open a second terminal, confirm the new key logs in, then close the first one.
- Use
ssh-copy-idinstead of copy-pasting keys by hand — it handles formatting and permissions correctly every time. - Keep console/VNC access enabled on your VPS as a fallback that doesn't depend on SSH at all.
- Set
IdentitiesOnly yesper host in~/.ssh/configif you manage multiple servers with different keys, so the right one is always offered first, instead of leaving it to guesswork:Host getwebup-vps HostName 203.0.113.10 User deploy IdentityFile ~/.ssh/id_ed25519_getwebup IdentitiesOnly yes - Snapshot before hardening changes — if a change to
sshd_configgoes wrong, restoring a snapshot from minutes earlier beats troubleshooting blind over console.
Once you've got access back, it's worth reading through SSH key and Fail2Ban hardening properly rather than patching this one error and moving on — the two problems usually show up together.