You type ssh user@your-vps-ip, hit enter, and instead of a shell prompt you get Permission denied (publickey). No password prompt, no second chance — just a flat refusal. If you've just hardened SSH (disabled password auth, maybe rotated keys) or switched laptops, this is one of the most common ways people lock themselves out of a VPS. The good news: it's almost always fixable without a reinstall, and there's a way back in even if SSH itself is broken.

Symptom: The Server Rejects Your Key Before Asking for Anything Else

The error itself tells you something useful. Permission denied (publickey) means the SSH handshake succeeded — the server is reachable, sshd is running, your network path is fine — but the server checked the public key you offered against ~/.ssh/authorized_keys for that user and didn't find a match. It never even got to asking for a password, because on a hardened server password auth is usually turned off entirely.

Run the connection with verbosity so you can see exactly what's happening instead of guessing:

ssh -v user@your-vps-ip

Look for lines like:

debug1: Offering public key: /home/you/.ssh/id_ed25519
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
Permission denied (publickey).

That "Offering public key" line matters — it tells you which key your local machine is actually sending. Half the time, that's the root of the problem right there.

Cause 1: You're Offering the Wrong Key

If you have more than one SSH key on your machine (a common setup once you use GitHub, other servers, or a work laptop), your SSH client might default to a key the server has never seen. Check what's in your local key ring:

ls -la ~/.ssh/

And force the correct one explicitly instead of relying on the default:

ssh -i ~/.ssh/id_ed25519_skyserver user@your-vps-ip

If that connects, the fix is to make it permanent. Add an entry to ~/.ssh/config on your local machine:

Host myvps
    HostName your-vps-ip
    User user
    IdentityFile ~/.ssh/id_ed25519_skyserver
    IdentitiesOnly yes

The IdentitiesOnly yes line is easy to skip and causes a surprising number of repeat tickets — without it, SSH will still try every key in your agent before the one you specified, which can trip server-side MaxAuthTries limits and get you rate-limited by Fail2Ban.

Cause 2: The Key Isn't Actually in authorized_keys

Maybe you generated a new key on a new laptop and never copied the public half over. Or you rebuilt the VPS from a snapshot that predates the key. Either way, if you still have another way in — your hosting provider's browser-based console, or a second key that still works — log in that way and check:

cat ~/.ssh/authorized_keys

Compare it against your local public key:

cat ~/.ssh/id_ed25519.pub

If it's missing, append it:

echo "ssh-ed25519 AAAA...your-key-here... you@laptop" >> ~/.ssh/authorized_keys

Don't use > here by accident — a single redirect overwrites the file and deletes every other key that was authorized, including the one you're currently connected with.

Cause 3: File Permissions Are Too Loose

This is the one that catches people out even when the key is correct and present. sshd is strict about ownership and permissions on the .ssh directory and its contents — if a backup tool, an FTP client, or a careless chmod -R loosened them, sshd silently refuses to trust the file rather than warn you. Set them back to the values sshd expects:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R user:user ~/.ssh

Also check the home directory itself — sshd will reject keys if the user's home folder is group- or world-writable:

chmod 755 /home/user

You can confirm exactly what sshd didn't like by watching the server-side log while you attempt the connection:

sudo tail -f /var/log/auth.log     # Debian/Ubuntu
sudo tail -f /var/log/secure       # AlmaLinux/Rocky/CentOS

A line like Authentication refused: bad ownership or modes for directory /home/user confirms it's a permissions issue, not a missing or wrong key.

Cause 4: sshd_config Is Blocking the User or Key Type

If you or someone else recently edited /etc/ssh/sshd_config as part of hardening, check for a few settings that commonly bite:

DirectiveWhat to check
PubkeyAuthenticationMust be yes
AllowUsers / AllowGroupsIf set, your username must be explicitly listed
PermitRootLoginIf no, root key logins will always be refused, even with a valid key
AuthorizedKeysFileConfirm it still points to .ssh/authorized_keys (default) and not a custom path that no longer exists

After any change to sshd_config, validate the syntax before reloading — a typo here can take SSH down entirely:

sudo sshd -t
sudo systemctl reload sshd

Use reload, not restart, where possible. A reload keeps your existing session alive if something's still wrong, whereas a botched restart can drop you with no way back in.

Cause 5: Fail2Ban or a Firewall Rule Is the Real Blocker

Occasionally the key is fine and the error is misleading you. If your IP address changed (new office, mobile hotspot, VPN) and you'd previously failed a few login attempts, Fail2Ban may have banned you at the firewall level before SSH even got to check your key. Test this from a different network (phone hotspot works well) — if that connects instantly, your old IP is banned. From the server console, check and unban:

sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip YOUR_OLD_IP

Recovery: When You're Fully Locked Out

If you have no working key and no other SSH access, don't panic and don't rebuild the server. Most VPS platforms, including SkyServer, provide a browser-based console (VNC/serial console) that bypasses SSH entirely and drops you into a root shell using your hosting panel login instead of an SSH key. From there you can:

  1. Log in via the console from your hosting control panel
  2. Add your current public key to ~/.ssh/authorized_keys for the correct user
  3. Fix any permissions or sshd_config issues found above
  4. Reload sshd and test the SSH connection from a second terminal window before closing the console session

That last point is the one people skip and then regret. Always keep the console (or an existing working session) open until you've confirmed the new key connects cleanly in a fresh terminal.

Prevention: Don't Get Locked Out Again

  • Keep at least two valid keys in authorized_keys from two different machines, so losing one laptop doesn't lock you out
  • Before disabling password authentication, confirm key-based login already works in a second terminal — never close your only working session while testing a change
  • Snapshot the VPS before editing sshd_config so a bad edit is a one-click rollback
  • Keep your hosting provider's browser console credentials handy and separate from your SSH keys — it's your safety net when SSH itself is the thing that's broken
  • Use ssh -v as your first troubleshooting step, always — it tells you which key was offered and exactly where the handshake failed, saving you from guessing

Frequently Asked Questions

Why does SSH say "Permission denied (publickey)" instead of showing a password prompt?

Because on most hardened servers, PasswordAuthentication is set to no in sshd_config. Once your key fails, there's no fallback method left to try, so the connection is refused immediately instead of prompting for a password.

Can wrong file permissions on my local machine cause this error?

Yes. If your private key file on your local machine is too open (for example, world-readable), some SSH clients will refuse to use it at all and skip straight to "no more authentication methods." Run chmod 600 ~/.ssh/id_ed25519 on your local key file too.

I can log in with the root user but not my regular user. What's different?

The two accounts have separate authorized_keys files at /root/.ssh/authorized_keys and /home/user/.ssh/authorized_keys. A key added for one user doesn't automatically work for the other — copy the public key into the correct user's file.

Does rebooting the VPS fix a publickey error?

Almost never. This is an authentication configuration issue, not a running-process issue, so a reboot won't change anything. Use the time instead to check permissions, sshd_config, and which key your client is offering.

I changed the SSH port and now I can't connect at all — is that the same problem?

No, that's a different symptom. If the connection times out or is refused before any authentication step, you're likely missing -p your_port on the client, or a firewall rule still only allows the old port. A true "Permission denied (publickey)" means the connection reached sshd and the handshake started — it's an auth problem, not a networking one.