Originally published at sshdock.com
Permission denied (publickey) means you successfully connected to the server over the network, but the server rejected your authentication. You are past the firewall. The SSH daemon is running. The problem is specifically that the server refused to accept your key.
This is different from Connection refused (SSH not running or firewall blocking port 22) and Connection timed out (server unreachable). Permission denied means the network is fine — it is the authentication step that failed.
Here is how to find and fix the actual cause.
What the server is actually checking
Before diving into fixes, here is what the server verifies when you connect with a key:
- Does
~/.ssh/authorized_keysexist on the server for your user? - Does it contain a line that matches your public key?
- Is
~/.ssh/set to permission700(not group or world writable)? - Is
~/.ssh/authorized_keysset to600(not group or world writable)? - Is the private key the correct pair for one of those public keys?
The server silently ignores authorized_keys if any permission check fails, and falls back to password auth (or rejects entirely). This is the most common source of confusion — the file exists with the right key, but wrong permissions means the server never reads it.
Step 1: Run SSH with verbose output
Add -vvv to your command first:
ssh -vvv user@your-server
Look for lines like:
debug1: Offering public key: /home/you/.ssh/id_ed25519 ED25519
debug1: Authentications that can continue: publickey
debug1: No more authentication methods to try.
If it says "Offering public key" but then moves on without success, the server received your key and rejected it. If it says "No identities found", your SSH agent is empty — skip to Step 3.
Step 2: Check authorized_keys on the server
If you have console access or password login, check the file and its permissions:
ls -la ~/.ssh/
cat ~/.ssh/authorized_keys
stat ~/.ssh/
stat ~/.ssh/authorized_keys
Permissions must be:
~/.ssh/ → 700 (drwx------)
authorized_keys → 600 (-rw-------)
Fix them if wrong:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Also verify ownership:
ls -la ~ | grep .ssh
# Should be owned by your user, not root
sudo chown -R youruser:youruser ~/.ssh
Step 3: Verify you are using the right key
Check what keys are loaded:
ls ~/.ssh/
ssh-add -l
If the agent is empty or missing your key:
ssh-add ~/.ssh/id_ed25519
Or specify the key file explicitly:
ssh -i ~/.ssh/my-specific-key.pem user@server
Compare your local public key to what is in authorized_keys on the server. A common mistake: the key pair was separated — the private and public keys are from different generations and do not match.
Step 4: Add the public key to the server
The most common scenario for new servers — you forgot to copy the public key.
If you have password access:
ssh-copy-id user@server
If ssh-copy-id is not available:
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Step 5: AWS EC2 — username and key pair issues
AWS has a few specific gotchas.
Wrong username. Each AMI uses a different default username:
| AMI | Username |
|---|---|
| Amazon Linux 2 / 2023 | ec2-user |
| Ubuntu | ubuntu |
| Debian | admin |
| CentOS / RHEL |
ec2-user or centos
|
| Fedora | fedora |
Key pair mismatch. EC2 instances are configured at launch with one specific key pair. Connecting with any other key will fail regardless of authorized_keys. The key pair cannot be changed through the console after launch.
PEM format. AWS .pem files are standard OpenSSH private keys — do not convert them unless you are using PuTTY.
Step 6: PasswordAuthentication is disabled
If password auth is disabled and your key fails, there is no fallback. The error looks identical.
Check the server config:
sudo grep -i passwordauthentication /etc/ssh/sshd_config
If you locked yourself out but have console access:
sudo sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config
sudo systemctl reload sshd
Connect with your password, fix the key setup, then re-disable password auth.
Step 7: SELinux (RHEL / CentOS / Amazon Linux)
SELinux can block SSH from reading authorized_keys even when file permissions look correct. Check:
sudo ausearch -m avc -ts today | grep ssh
sudo tail -f /var/log/audit/audit.log | grep denied
Fix with:
restorecon -Rv ~/.ssh
This is common when .ssh/ was created by copying files manually rather than through ssh-keygen or ssh-copy-id.
Step 8: Read the server-side logs
The server logs the exact reason for auth failures — far more detail than the client output:
sudo tail -f /var/log/auth.log # Ubuntu/Debian
sudo tail -f /var/log/secure # RHEL/CentOS/Amazon Linux
sudo journalctl -u sshd -f # Systemd systems
Watch while making a connection attempt. You will see exactly what failed:
Authentication refused: bad ownership or modes for directory /home/user/.ssh
Quick diagnostic checklist
# Local machine: what key is being offered?
ssh -vvv user@server 2>&1 | grep -E "(Offering|denied|refused|try)"
# Keys loaded in agent?
ssh-add -l
# Force a specific key:
ssh -i ~/.ssh/correct-key.pem user@server
# On the server: check if your public key is in authorized_keys
cat ~/.ssh/authorized_keys | grep "$(cat ~/.ssh/id_ed25519.pub | awk '{print $2}')"
If you need to SSH from a browser without any local setup, SSHDock is a free web-based SSH client that handles RSA and Ed25519 PEM keys directly — no conversion or agent setup needed.
For a complete key setup walkthrough, see the SSH key authentication guide.
Top comments (0)