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

The server refused every key your client offered, or your client offered none. Run ssh -v user@server to see which keys are offered, then read the auth log on the server to see why they were refused. The usual causes are a key that is not in the server's authorized_keys, the wrong user name, or bad permissions on ~/.ssh or the home directory. If password login still works, ssh-copy-id user@server installs your key.

Updated . Each failure was reproduced with OpenSSH 10.3 on macOS against OpenSSH 10.0 on Debian 13, and the log lines are from those runs. ssh-copy-id and the manual install were run against OpenSSH 10.0 on Debian 13.

See what your client offers

ssh -v user@server

Look for these lines near the end of the output:

LineWhat it means
Will attempt key: ...The keys your client plans to try. If yours is missing, the client does not know about it.
Offering public key: ...The key was sent to the server.
Server accepts key: ...The server knows this key. A failure after this line is a problem with the private key on your side.
Warning: Identity file ... not accessibleThe path you gave to -i or IdentityFile does not exist.
Load key "...": bad permissionsThe private key file is too open, so it was ignored. See unprotected private key file.

The word in brackets in the error lists the login methods the server still allows. (publickey) alone means passwords are off, so a working key is the only way in.

Getting this from git push or git pull? See git@github.com: Permission denied (publickey).

Read the log on the server

The client is never told why a key was refused. Only the server knows. If you still have a way in, such as another session or a provider console, read the log:

sudo journalctl -u ssh -n 50     # Debian, Ubuntu
sudo journalctl -u sshd -n 50    # RHEL, Fedora, Arch
sudo tail -n 50 /var/log/auth.log   # older Debian and Ubuntu
sudo tail -n 50 /var/log/secure     # older RHEL
Log lineCause
Invalid user alice from ...That account does not exist on the server.
Authentication refused: bad ownership or modes for directory ...Permissions on the home directory or .ssh.
Authentication refused: bad ownership or modes for file ...Permissions on authorized_keys.
Could not open user 'user' authorized keys ...: Permission deniedThe file belongs to someone else, often root, after being created with sudo.
User user from ... not allowed because not listed in AllowUsersThe account is blocked by AllowUsers. DenyUsers, AllowGroups and DenyGroups work in a similar way.
Connection closed by authenticating user user ... [preauth]Nothing else logged usually means the key is simply not in authorized_keys.

If the log gives no reason, run a second sshd in debug mode on a spare port. It handles one connection, prints every step, and exits. The port must be open in your firewall.

sudo /usr/sbin/sshd -d -p 2222
ssh -v -p 2222 user@server

Wrong user

Check who you are really logging in as, because a User line in your config may set it:

ssh -G server | grep '^user '

Cloud images often use a fixed account such as ubuntu, debian or ec2-user, and refuse root. A key installed for one account does not work for another, because each account has its own authorized_keys.

To fix the user and key for a host once, put User and IdentityFile in its block of your ssh config file.

Wrong key, or no key on the server

Compare fingerprints. On your machine:

ssh-keygen -lf ~/.ssh/id_ed25519.pub

On the server, this lists every key in the file:

ssh-keygen -lf ~/.ssh/authorized_keys

If the fingerprint is missing, install the key. While password login still works, one command does it, with the right permissions:

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

If the server takes only keys, add it from a provider console or another session, as that user. Put your whole .pub line in place of the example:

mkdir -p ~/.ssh && chmod 700 ~/.ssh
echo 'ssh-ed25519 AAAA... you@laptop' >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

If the key is there but your client offers others first, name it and ignore the rest:

ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 user@server

A common mistake when installing by hand is a key split over two lines. Each key must be on one line: see the authorized_keys file explained.

Permissions and ownership

With the default StrictModes yes, sshd ignores authorized_keys if other users could write to it or to the directories above it. Group write on the home directory is enough to trigger it. On the server, as the user:

chmod go-w ~
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

If you created the files with sudo, fix the owner as well:

sudo chown -R user:user /home/user/.ssh

To see every level of the path at once:

namei -l /home/user/.ssh/authorized_keys

On systems with SELinux enforcing, such as RHEL and Fedora, files moved into place can also carry the wrong label. Reset it with restorecon -Rv ~/.ssh.

AuthorizedKeysFile points elsewhere

Your key may be in the right file for the default setup, but not for this server. Ask sshd what applies to this user. -C also evaluates any Match blocks:

sudo sshd -T -C user=user,host=example.com,addr=203.0.113.10 | grep -iE '^(authorizedkeysfile|pubkeyauthentication) '

The default is .ssh/authorized_keys .ssh/authorized_keys2, relative to the home directory. A value like /etc/ssh/authorized_keys/%u means the key has to go there instead. Also check that pubkeyauthentication says yes.

Old RSA and PubkeyAcceptedAlgorithms

OpenSSH 8.8 turned off the ssh-rsa signature, which uses SHA-1, by default. This disabled the old signature, not RSA keys. An RSA key still works when both sides support rsa-sha2-256 or rsa-sha2-512, which OpenSSH has supported since version 7.2.

If a new client meets a server too old for that, ssh -v shows a line such as no mutual signature algorithm, and the key is never offered. Upgrading the server is the real fix. Until then, allow the old signature for that one host in ~/.ssh/config:

Host oldbox
  PubkeyAcceptedAlgorithms +ssh-rsa
  HostKeyAlgorithms +ssh-rsa

If an old client connects to a new server, the same line goes in sshd's configuration, and affects every user of that server:

PubkeyAcceptedAlgorithms +ssh-rsa

Before OpenSSH 8.5 the option was called PubkeyAcceptedKeyTypes. If you can, switch to an ed25519 key and remove these lines.

Questions

How do I add my SSH key to the server?

Run ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server while password login still works. If the server accepts only keys, append your .pub line to ~/.ssh/authorized_keys from a provider console, then run chmod 600 on the file.

Why does SSH say Permission denied (publickey) when the key is on the server?

Usually permissions: sshd ignores authorized_keys if others can write to the home directory, .ssh or the file. Also check that the key is in the file of the account you log in as.

How do I see which key SSH is offering?

Run ssh -v user@server and look for the Offering public key lines. To use only one key, add -o IdentitiesOnly=yes and -i with its path.

Do RSA keys still work with recent OpenSSH?

Yes. OpenSSH 8.8 turned off the old ssh-rsa signature with SHA-1, not RSA keys, which work with rsa-sha2-256 or rsa-sha2-512.

Sources

More in Keys and login

All guides