devkult_
tools29converters34
home/blog/ssh-permission-denied-publickey
sshlinuxsecurity

How to Fix "Permission denied (publickey)" in SSH

Permission denied (publickey). is the server telling you two things: it only accepts key-based logins, and none of the keys your client offered were accepted. The cause is almost always one of a handful of things — and ssh -v will tell you which.

Step 1: watch the handshake

ssh -v user@host

The lines that matter:

debug1: Authentications that can continue: publickey
debug1: Offering public key: /home/you/.ssh/id_ed25519 ED25519 SHA256:…
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.

You now know which keys were offered and that the server refused each one. If the key you expected isn't in the list, the problem is on your side; if it was offered and refused, it's on the server's.

Wrong username

Each cloud image has its own default user: ubuntu on Ubuntu, ec2-user on Amazon Linux, admin on Debian AMIs, and often root elsewhere. For GitHub and GitLab, the user is always git:

ssh -T git@github.com
# Hi your-name! You've successfully authenticated, but GitHub does not provide shell access.

The right key isn't being offered

Point ssh at the key explicitly:

ssh -i ~/.ssh/my-server-key user@host

To make that permanent, add a block to ~/.ssh/config:

Host myserver
  HostName 203.0.113.10
  User ubuntu
  IdentityFile ~/.ssh/my-server-key
  IdentitiesOnly yes

IdentitiesOnly yes stops ssh offering every key in your agent first. Servers give up after a few failed attempts, so an agent holding many keys can trigger Too many authentication failures before the right one is tried.

Your public key isn't on the server

The server checks ~/.ssh/authorized_keys for the user you log in as. Add your public key with:

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

If you can't log in at all, add it through your cloud provider's console or a recovery shell.

Permissions on the server are too open

With its default StrictModes, sshd ignores authorized_keys if the files are writable by others. The server's auth log says so explicitly — Authentication refused: bad ownership or modes in /var/log/auth.log (or journalctl -u ssh). Fix the modes:

chmod go-w ~                     # home directory: not writable by group or others
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

(700 and 600 explained.)

Permissions on your private key are too open

The client has its own check. If your private key is readable by other users, ssh refuses to use it:

WARNING: UNPROTECTED PRIVATE KEY FILE!
Permissions 0644 for '/home/you/.ssh/id_ed25519' are too open.
chmod 600 ~/.ssh/id_ed25519   # or 400, read-only

Public keys (.pub) can stay at 644; only the private half must be private. AWS's .pem keys need the same treatment — that's why its guides say chmod 400.

The agent doesn't have your key

If you rely on ssh-agent, check what it holds:

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

On macOS, ssh-add --apple-use-keychain ~/.ssh/id_ed25519 stores the passphrase in the Keychain so it survives reboots.

Old RSA keys and old servers

OpenSSH 8.8 (2021) disabled RSA signatures using SHA-1 (ssh-rsa) by default. A modern client connecting to an old server that only supports ssh-rsa, or an old client meeting a hardened server, can end in Permission denied with an RSA key that worked for years. The clean fix is a modern key:

ssh-keygen -t ed25519 -C "you@example.com"

Then add the new public key to the server or to GitHub.

Quick checklist

  1. ssh -v — which keys are offered?
  2. Right user for this server?
  3. Right key — -i or IdentityFile, with IdentitiesOnly yes?
  4. Public key in the server's authorized_keys?
  5. Server: home not group-writable, ~/.ssh 700, authorized_keys 600.
  6. Client: private key 600 or 400.
  7. Still stuck with an old RSA key? Generate an ed25519 key.

For any other permission combination, the chmod calculator shows exactly who can do what.

More from the blog