Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Linux Admins By James Joyner IV · · 10 min read

Linux Error Guide: 'Permission denied (publickey)' SSH Key Authentication Failures

Fix SSH 'Permission denied (publickey)': diagnose missing keys, authorized_keys, file permissions, StrictModes, wrong user, ssh-agent, and disabled key types.

  • #linux
  • #troubleshooting
  • #errors
  • #ssh

Overview

Permission denied (publickey) means the SSH server rejected every authentication method the client offered and the only method it would accept was public-key — which also failed. The client either presented no usable key, presented a key the server does not trust, or the server refused to read the key because of permissions, a disabled algorithm, or a configuration restriction. Because public-key was the last (or only) method left, the connection is closed with this message.

You will see it on the client when the handshake ends:

client@workstation:~$ ssh deploy@web-01
deploy@web-01: Permission denied (publickey).

With verbose output the client shows it exhausting its keys before the rejection:

debug1: Offering public key: /home/client/.ssh/id_ed25519 ED25519 SHA256:abc123...
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
deploy@web-01: Permission denied (publickey).

It occurs at authentication time — after the TCP connection and key exchange succeed — so the host is reachable and sshd is running. The failure is purely about which key is offered and whether the server will accept it, which is why the same key can work for one user or host and fail for another.

Symptoms

  • ssh user@host ends immediately with Permission denied (publickey) and no password prompt.
  • git clone/git pull over SSH fails with the same message.
  • The server’s auth log records Connection closed by authenticating user ... [preauth] or Failed publickey.
  • ssh -v shows keys offered but Authentications that can continue: publickey with no success.
ssh -vvv deploy@web-01 2>&1 | grep -E 'Offering|Authentications|Server accepts|Permission denied'
debug1: Offering public key: /home/client/.ssh/id_ed25519 ED25519 SHA256:abc123...
debug1: Server accepts key: /home/client/.ssh/id_ed25519 ED25519 SHA256:abc123...
debug1: Authentications that can continue: publickey
deploy@web-01: Permission denied (publickey).

Common Root Causes

1. The wrong key is offered, or no key at all

The client offers keys from its defaults or agent; if the matching private key is not among them (or IdentityFile points elsewhere), nothing the server trusts is presented.

ssh -v deploy@web-01 2>&1 | grep -E 'Will attempt|Offering|Trying private key'
ssh -G deploy@web-01 | grep -i identityfile
debug1: Will attempt key: /home/client/.ssh/id_rsa RSA SHA256:zzz...
debug1: Offering public key: /home/client/.ssh/id_rsa RSA SHA256:zzz...
identityfile ~/.ssh/id_rsa

Only id_rsa is offered, but the account’s authorized_keys holds an ed25519 key — the right key is never presented. Force the correct one with ssh -i ~/.ssh/id_ed25519 deploy@web-01.

2. The public key is not in the server’s authorized_keys

The key the client offers must have a matching entry in the target user’s ~/.ssh/authorized_keys on the server.

# On the server, as the target user:
ssh-keygen -lf ~/.ssh/authorized_keys
# Compare to the client key fingerprint:
ssh-keygen -lf ~/.ssh/id_ed25519.pub
# server authorized_keys:
256 SHA256:def456... deploy@old-laptop (ED25519)
# client key being offered:
256 SHA256:abc123... client@workstation (ED25519)

The fingerprints differ (def456 vs abc123) — the client’s key was never installed. Append it: ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@web-01 (using another working method), or paste the .pub line into authorized_keys.

3. Wrong permissions on ~/.ssh or authorized_keys

sshd ignores authorized_keys if it or its directory is group/world-writable. Expected: ~/.ssh is 700, authorized_keys is 600.

# On the server, as the target user:
stat -c '%a %n' ~ ~/.ssh ~/.ssh/authorized_keys
755 /home/deploy
775 /home/deploy/.ssh
664 /home/deploy/.ssh/authorized_keys

.ssh is 775 and authorized_keys is 664 — both group-writable, so sshd silently refuses them. Fix:

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

4. Home directory too open with StrictModes on

StrictModes yes (the default) makes sshd reject keys if the user’s home directory itself is group- or world-writable, even when .ssh is correct.

# On the server:
grep -i strictmodes /etc/ssh/sshd_config
sudo journalctl -u ssh --no-pager | grep -i 'bad ownership\|authentication refused' | tail -3
StrictModes yes
sshd[2841]: Authentication refused: bad ownership or modes for directory /home/deploy

The home directory is writable by group/other; with StrictModes yes that alone blocks key auth. Tighten it: chmod 750 /home/deploy (or 700).

5. Wrong username

The key is correct but installed under a different account than the one being connected to; the server looks in the wrong authorized_keys.

ssh -v root@web-01 2>&1 | grep -E 'Authenticating to|Offering'
# On the server, confirm which user owns the key:
sudo ssh-keygen -lf /home/deploy/.ssh/authorized_keys
debug1: Authenticating to web-01:22 as 'root'
debug1: Offering public key: /home/client/.ssh/id_ed25519 ED25519 SHA256:abc123...
256 SHA256:abc123... client@workstation (ED25519)

The key lives in deploy’s authorized_keys, but the connection is as 'root'sshd checks /root/.ssh/authorized_keys, finds nothing. Connect as deploy@web-01.

6. Agent not loaded or key type disabled by the server

If ssh-agent holds no key the client may offer nothing; separately, modern sshd disables legacy ssh-rsa (SHA-1) so an old RSA key is rejected even when present.

ssh-add -l
# On the server, what does sshd accept?
sudo sshd -T | grep -iE 'pubkeyauthentication|authorizedkeysfile|pubkeyacceptedalgorithms|allowusers'
The agent has no identities.
pubkeyauthentication yes
authorizedkeysfile .ssh/authorized_keys
pubkeyacceptedalgorithms ssh-ed25519,ecdsa-sha2-nistp256,rsa-sha2-512,rsa-sha2-256
allowusers deploy

The agent is empty (so no key is auto-offered — run ssh-add ~/.ssh/id_ed25519), and pubkeyacceptedalgorithms lacks ssh-rsa, so a SHA-1 RSA key would be refused. allowusers deploy also confirms only deploy may log in.

Diagnostic Workflow

Step 1: Run the client with verbose output

ssh -vvv deploy@web-01 2>&1 | grep -E 'as |Offering|Server accepts|Authentications|Permission denied'

Confirm which user you authenticate as, which keys are offered, and whether the server even accepts one before the rejection.

Step 2: Verify the agent and identity files

ssh-add -l
ssh -G deploy@web-01 | grep -i identityfile

If the agent is empty, add the key (ssh-add ~/.ssh/id_ed25519); if the wrong IdentityFile is resolved, force the right one with -i.

Step 3: Match client key fingerprint to server authorized_keys

ssh-keygen -lf ~/.ssh/id_ed25519.pub                 # client
# on the server, as target user:
ssh-keygen -lf ~/.ssh/authorized_keys                # server entries

The offered fingerprint must appear in the server list. If it does not, install the key.

Step 4: Check server-side permissions and modes

# on the server, as target user:
stat -c '%a %n' ~ ~/.ssh ~/.ssh/authorized_keys
grep -i strictmodes /etc/ssh/sshd_config

Expect 700 on .ssh, 600 on authorized_keys, and a home directory not writable by group/other.

Step 5: Read the server auth log and effective sshd config

sudo journalctl -u ssh --since "5 min ago" --no-pager | tail -20
sudo tail -20 /var/log/auth.log
sudo sshd -T | grep -iE 'pubkeyauthentication|authorizedkeysfile|pubkeyacceptedalgorithms|allowusers|allowgroups'

The log gives the precise reason (bad ownership, Failed publickey, User not allowed), and sshd -T shows the running policy after all includes/Match blocks.

Example Root Cause Analysis

A new engineer cannot reach the build host: ssh deploy@build-02 returns Permission denied (publickey). The key was definitely added to authorized_keys an hour ago, and other engineers connect fine.

Verbose client output shows the right key is offered and even accepted by the server, yet auth still fails:

ssh -vvv deploy@build-02 2>&1 | grep -E 'Server accepts|Authentications|Permission denied'
debug1: Server accepts key: /home/eng/.ssh/id_ed25519 ED25519 SHA256:abc123...
debug1: Authentications that can continue: publickey
deploy@build-02: Permission denied (publickey).

“Server accepts key” but then “Permission denied” is the classic permissions signature — sshd recognized the key but refused to honor the file. The server auth log confirms it:

sudo journalctl -u ssh --since "10 min ago" --no-pager | grep -i deploy
sshd[5102]: Authentication refused: bad ownership or modes for directory /home/deploy/.ssh

Checking the modes on the server:

stat -c '%a %n' /home/deploy/.ssh /home/deploy/.ssh/authorized_keys
770 /home/deploy/.ssh
640 /home/deploy/.ssh/authorized_keys

When the key was pasted in, the editor (and a permissive umask) left .ssh group-writable at 770 and authorized_keys at 640. With StrictModes yes, sshd refuses to use a group-writable .ssh.

Fix: tighten the directory and file, then retry:

sudo chmod 700 /home/deploy/.ssh
sudo chmod 600 /home/deploy/.ssh/authorized_keys
sudo chown -R deploy:deploy /home/deploy/.ssh

With .ssh at 700 and authorized_keys at 600, the next ssh deploy@build-02 authenticates immediately.

Prevention Best Practices

  • Bake correct permissions into provisioning: ~/.ssh at 700, authorized_keys at 600, home directory not group/world-writable, all owned by the user — most failures are a single bad mode.
  • Install keys with ssh-copy-id rather than hand-pasting, which preserves modes and avoids stray whitespace that silently breaks an entry.
  • Standardize on ed25519 keys and keep PubkeyAcceptedAlgorithms current so deprecated ssh-rsa (SHA-1) keys do not fail after an OpenSSH upgrade.
  • Load keys into ssh-agent (or use a config IdentityFile/AddKeysToAgent yes) so the right key is always offered, and audit sshd -T after any config change to confirm AllowUsers/Match blocks still permit your accounts. More operational references live in the Linux admins category.
  • Keep StrictModes yes and monitor auth.log for bad ownership or modes and Failed publickey so a broken key install is caught before it blocks a deploy.
  • Always keep one verified out-of-band access path (console, a second authorized key) before editing sshd_config, so a mistake never locks everyone out.

Quick Command Reference

# Client: see exactly what is offered and accepted
ssh -vvv deploy@host 2>&1 | grep -E 'as |Offering|Server accepts|Authentications|Permission denied'
ssh -G deploy@host | grep -i identityfile

# Agent: is a key loaded?
ssh-add -l
ssh-add ~/.ssh/id_ed25519

# Force a specific key
ssh -i ~/.ssh/id_ed25519 deploy@host

# Match fingerprints (client vs server)
ssh-keygen -lf ~/.ssh/id_ed25519.pub          # client
ssh-keygen -lf ~/.ssh/authorized_keys         # on server, target user

# Server: permissions and StrictModes
stat -c '%a %n' ~ ~/.ssh ~/.ssh/authorized_keys
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

# Server: effective config and logs
sudo sshd -T | grep -iE 'pubkeyauthentication|authorizedkeysfile|pubkeyacceptedalgorithms|allowusers'
sudo journalctl -u ssh --since "5 min ago" --no-pager | tail -20
sudo tail -20 /var/log/auth.log

# Install a key correctly
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@host

Conclusion

Permission denied (publickey) is an authentication failure, not a connectivity problem — the host is reachable and sshd is running; the server simply would not accept any key the client offered. Verbose client output plus the server’s auth log narrow it down fast: “Server accepts key” then a denial points at permissions, while “no key offered” points at the agent or IdentityFile. The usual root causes:

  1. The wrong key (or no key) is offered, so nothing the server trusts is presented.
  2. The client’s public key is not present in the target user’s authorized_keys.
  3. Wrong permissions on ~/.ssh (700) or authorized_keys (600) make sshd ignore them.
  4. A group/world-writable home directory blocks key auth under StrictModes yes.
  5. Connecting as the wrong username, so sshd checks a different authorized_keys.
  6. An empty ssh-agent, or a deprecated ssh-rsa key type the server no longer accepts.

Start with ssh -vvv and the server auth.log, then verify fingerprints and modes — almost every case is a missing key entry or a single permission set too loosely.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.