SSH: 'Permission Denied (publickey)'

The server rejected your key. 90% of cases are wrong permissions, wrong key, or the right key on the wrong account.

What you'll see

Root causes

File permissions too open

sshd refuses keys with permissive permissions: ~/.ssh or authorized_keys group/world readable.

Offering the wrong key

ssh is silently offering a different key than you think. -v reveals the offer list.

Target user has no authorized_keys entry

Right key, wrong account — or the cloud provider's key was never added for this username.

Fix it

  1. Watch which keys are actually offered
    ssh -v user@host 2>&1 | grep -i 'offering'
  2. Fix permissions on both ends
    chmod 700 ~/.ssh && chmod 600 ~/.ssh/id_ed25519 ~/.ssh/authorized_keys
  3. Be explicit about identity and user
    ssh -i ~/.ssh/id_ed25519 deploy@host -o IdentitiesOnly=yes
  4. On the server, check sshd accepts keys and see the refusal
    sudo journalctl -u ssh -n 50   # or /var/log/auth.log

Field note

sshd logs the real reason server-side ('Authentication refused: bad ownership'). Client-side -v tells you what you offered; server logs tell you why it was refused.

Common questions

I verified my key is in authorized_keys. Why still denied?

The server rejects at a stage before the key comparison: wrong permissions on the home dir, .ssh (700), or authorized_keys (600), or SELinux contexts. sshd's log (LogLevel DEBUG) names the exact failing check — use ssh -v and compare.

Why does it fail for root but work for other users?

PermitRootLogin defaults to prohibit-password, which accepts keys — but many distros ship it as no. Check sshd_config for the root-specific policy before assuming the key is the problem.

Ship it right the first time

Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.

Browse the template store →

One-time. Yours to modify. Instant download from the NinjaOps template store.