SSH Permission Denied (publickey): How to Fix It


You try to connect and the server closes the door:

user@host: Permission denied (publickey).

This message means the server rejected every key your client offered. It is not a network problem and not a password problem — password authentication is disabled, which is why no prompt appeared. The fastest way to find the real reason is to make SSH tell you what it tried.

Key Takeaways

  • Permission denied (publickey) means the server refused all offered keys, so the fix is always about keys, paths, or permissions.
  • Running ssh with -vvv shows exactly which key files the client offered and whether the server rejected them.
  • SSH silently ignores authorized_keys if the home directory, .ssh directory, or the file itself is group or world writable.
  • Connecting as the wrong username is a frequent cause, since each cloud image has its own default account.
  • Keep a second authenticated session open while editing SSH configuration so a mistake cannot lock you out.

Quick Fix

Run ssh with verbose output to see which key was offered and how the server responded. That single command usually identifies whether the problem is the wrong key, the wrong username, or a permissions issue on the server.

ssh -vvv user@host

Start With Verbose Output

Guessing wastes time. Ask SSH to narrate the handshake:

ssh -vvv user@host

Scroll to the lines beginning debug1: Offering public key:. They list every key your client tried, in order. Three patterns tell you where to look next:

  • No keys offered at all — your client cannot find a key. Go to the client-side section below.
  • Keys offered, all refused — the server does not have your public key, or cannot read it. Go to the server-side sections.
  • Correct key offered then refused — almost always a permissions problem on the server.

Cause 1: You Are Connecting as the Wrong User

This is the most common cause on cloud servers and the easiest to overlook, because the error looks identical to a key problem. Your key is installed for one account, and you are logging in as another.

Default accounts vary by image: ubuntu on Ubuntu images, ec2-user on Amazon Linux, admin or debian on Debian, root on many DigitalOcean and Hetzner images, and often a custom name on anything you built yourself.

Try the expected account for your image:

ssh -vvv ubuntu@host

If you have configured a host alias, check what username it is actually using — an outdated entry here causes exactly this error:

grep -A5 "Host myserver" ~/.ssh/config

Cause 2: The Client Is Not Offering the Right Key

If the verbose output offered no keys, or only keys you do not use for this host, point SSH at the right one explicitly:

ssh -i ~/.ssh/id_ed25519 user@host

If that works, make it permanent so you do not need the flag every time. Add an entry to ~/.ssh/config:

Host myserver
    HostName 203.0.113.10
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519

Your private key must also be readable only by you, or SSH refuses to use it and warns loudly about an unprotected key file:

chmod 600 ~/.ssh/id_ed25519

If your key is protected by a passphrase and you are automating the connection, load it into the agent once per session:

ssh-add ~/.ssh/id_ed25519
ssh-add -l

The second command lists loaded keys, confirming the agent is holding the one you expect.

Cause 3: Permissions on the Server Are Too Loose

This one is uniquely frustrating because everything looks correct. SSH deliberately ignores authorized_keys if the file, the .ssh directory, or the home directory can be written by anyone other than the owner — a safeguard against another user planting a key.

You need an existing session, a cloud provider’s web console, or a rescue shell to fix this. From that session, on the server:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 755 ~

Then confirm ownership is the login user rather than root, which is a frequent side effect of creating the file with sudo:

ls -ld ~ ~/.ssh ~/.ssh/authorized_keys

If any of those show root as owner for a non-root account, correct it:

sudo chown -R $USER:$USER ~/.ssh

When you are locked out entirely and the permissions are wrong, the server’s own logs confirm the diagnosis. From a console session:

sudo journalctl -u ssh -n 30 --no-pager

Messages mentioning bad ownership or modes for a directory are conclusive.

Cause 4: The Public Key Is Missing or Malformed

Confirm the server actually holds the key you are offering. Print your public key locally:

cat ~/.ssh/id_ed25519.pub

And compare against what the server has:

cat ~/.ssh/authorized_keys

Each entry must sit on exactly one line. A key broken across several lines by a copy-paste through a text editor will never match. If you need to add it again and can still reach the server another way, append it safely:

echo 'ssh-ed25519 AAAA... user@laptop' >> ~/.ssh/authorized_keys

Note the double angle bracket. Using a single one overwrites the file and removes every other key, which can lock out other users and, on many cloud images, your provider’s own recovery access.

Cause 5: Server Configuration Excludes You

If the key is present, permissions are correct, and it still fails, the daemon’s configuration may be excluding your account. Check the relevant directives:

sudo grep -E "^(PubkeyAuthentication|AllowUsers|AllowGroups|PermitRootLogin|AuthorizedKeysFile)" /etc/ssh/sshd_config

Watch for three things. AllowUsers or AllowGroups restricts logins to a list — if your account is not on it, no key will work. PermitRootLogin prohibit-password is fine for key-based root login, but no blocks it entirely. And a customised AuthorizedKeysFile path means the server is reading keys from somewhere other than where you put them.

Before restarting the daemon after any edit, validate the file and keep your current session open:

sudo sshd -t && sudo systemctl reload ssh

The -t flag catches syntax errors that would otherwise stop sshd from restarting and lock everyone out.

Verify the Fix

Open a second terminal and connect while leaving your working session untouched:

ssh -o BatchMode=yes user@host 'echo connected'

BatchMode=yes prevents any interactive prompt, so a success here proves key authentication works on its own. Only close your original session once this succeeds.

Prevent It From Happening Again

Use ssh-copy-id rather than editing authorized_keys by hand — it sets the correct permissions and appends instead of overwriting:

ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host

Record each server in ~/.ssh/config with its correct username and key, so you never rely on remembering which account a given image uses. And when hardening a server, keep an authenticated session open until you have proven the new configuration works from a fresh one. Nearly every permanent lockout traces back to closing the last good session too early.

Frequently Asked Questions

Why does my key work from one machine but not another?

Each machine has its own key pair. The public key from the second machine must also be added to authorized_keys on the server. Run ssh-copy-id from the new machine, or append its public key to the server’s authorized_keys file.

I can connect as root but not as my user. Why?

The key is installed in root’s authorized_keys but not in your user’s. Each account has a separate ~/.ssh/authorized_keys file. Copy the key into your user’s file and make sure the directory and file are owned by that user.

Does this error mean I was hacked or blocked?

No. It is the normal response when no offered key is accepted. A blocked IP typically produces a connection timeout or refusal instead, and fail2ban bans show up as a dropped connection rather than an authentication message.

Why did it start failing right after I enabled key-only login?

Disabling password authentication removes the fallback that was masking a key problem. The key was never working; you were logging in by password. Fix the key with the steps above from a console session.

Scroll to Top