How to Fix SSH 'Permission denied (publickey)' Error
Step-by-step guide to diagnose and fix SSH 'Permission denied (publickey)' errors on Linux, macOS, and Windows using ssh-add, ssh -vvv, and permissions.
How to Fix SSH "Permission denied (publickey)" Error
\nThe dreaded Permission denied (publickey) message means the SSH server rejected every authentication method your client offered. It is almost never a network or password problem — the server saw your connection, refused the key, and closed the door. This guide walks through the five checks that resolve virtually every case, with real command output so you know what "good" looks like.
1. Is your key loaded in ssh-agent?
\nStart by asking the agent what it holds:
\n$ ssh-add -l\nThe agent has no identities.\nThat empty state is a common cause. Load your private key:
\n$ ssh-add ~/.ssh/id_ed25519\nEnter passphrase for /home/badshah/.ssh/id_ed25519:\nIdentity added: /home/badshah/.ssh/id_ed25519 (badshah@laptop)\nIf ssh-add itself fails with Could not open a connection to your authentication agent, start the agent first: eval "$(ssh-agent -s)".
2. Does the server actually have your public key?
\nGet into the server another way (password login, cloud console, or recovery shell) and check:
\n$ cat ~/.ssh/authorized_keys\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... badshah@laptop\nCompare the fingerprint of what is on the server with what your client is sending:
\n$ ssh-keygen -lf ~/.ssh/id_ed25519.pub\n256 SHA256:Xk3q9... badshah@laptop (ED25519)\nThey must match byte-for-byte. A stray line break in authorized_keys silently invalidates the entry.
3. Are the permissions correct?
\nOpenSSH refuses to use keys that other users can read. On the server:
\nchmod 700 ~/.ssh\nchmod 600 ~/.ssh/authorized_keys\nchown -R $USER:$USER ~/.ssh\nOn the client:
\nchmod 700 ~/.ssh\nchmod 600 ~/.ssh/id_ed25519\nchmod 644 ~/.ssh/id_ed25519.pub\nIf permissions were wrong, ssh -vvv will have shown lines like Permissions 0644 for '/home/badshah/.ssh/id_ed25519' are too open and this private key will be ignored.
4. Is the right key being offered?
\nRun verbose SSH to watch the negotiation:
\n$ ssh -vvv [email protected]\ndebug1: Offering public key: /home/badshah/.ssh/id_rsa RSA SHA256:abcd...\ndebug1: Authentications that can continue: publickey\ndebug1: Offering public key: /home/badshah/.ssh/id_ed25519 ED25519 SHA256:Xk3q9...\ndebug1: Server accepts key: /home/badshah/.ssh/id_ed25519 ED25519 SHA256:Xk3q9...\nIf the client stops after a few keys with Too many authentication failures, pin the exact key and disable identity guessing:
\nssh -i ~/.ssh/id_ed25519 -o IdentitiesOnly=yes [email protected]\nThen make it permanent in ~/.ssh/config:
Host example.com\n IdentityFile ~/.ssh/id_ed25519\n IdentitiesOnly yes\n User badshah\n\n5. Is SELinux or AppArmor blocking access?
\nOn RHEL, Fedora, Rocky, or AlmaLinux, authorized_keys can have correct Unix permissions but the wrong SELinux label — especially if you copied it in from another location. Fix the labels:
$ restorecon -R -v /home/badshah/.ssh\nRelabeled /home/badshah/.ssh from unconfined_u:object_r:user_home_t:s0 to unconfined_u:object_r:ssh_home_t:s0\nRelabeled /home/badshah/.ssh/authorized_keys from unconfined_u:object_r:user_home_t:s0 to unconfined_u:object_r:ssh_home_t:s0\nCheck for denials:
\nausearch -m AVC -ts recent | grep ssh\nOn Ubuntu with AppArmor, review /var/log/syslog for apparmor="DENIED" lines mentioning sshd.
Windows OpenSSH gotchas
\nThe built-in OpenSSH on Windows 10/11 is strict about ACLs and unforgiving of PowerShell profile clutter. Common fixes:
\n- \n
- Agent not running.
Get-Service ssh-agentshould show Running. Enable it once:Set-Service ssh-agent -StartupType Automatic; Start-Service ssh-agent. \n - Key permissions rejected. Windows uses ACLs, not chmod. Lock the key to your user only:\n
\nicacls C:\\Users\\Badshah\\.ssh\\id_ed25519 /inheritance:r\nicacls C:\\Users\\Badshah\\.ssh\\id_ed25519 /grant:r "$($env:USERNAME):(R)"\n - Wrong OpenSSH on PATH. If Git for Windows ships its own
ssh.exeahead of the Windows one, they use different agents and different key stores. Run(Get-Command ssh).Sourceto confirm which one you are using. \n - CRLF in authorized_keys. If you edited the file in Notepad, the line endings may be CRLF and sshd will not match the key. Re-save as LF-only using VS Code or
dos2unix. \n
When nothing else works
\nAsk the server to log the reason. As root on the server:
\ntail -f /var/log/auth.log # Debian/Ubuntu\njournalctl -u sshd -f # systemd distros\nYou will see messages like Authentication refused: bad ownership or modes for directory /home/badshah or User badshah from 1.2.3.4 not allowed because listed in DenyUsers. Those log lines identify the exact rejection cause and take you straight to the fix.
" }