Fix: SSH Permission denied (publickey,password)
Part of: Docker, DevOps & Infrastructure
Quick Answer
How to fix SSH permission denied publickey password error caused by wrong SSH key, incorrect server config, disabled password auth, wrong username, and file permission issues.
The Error
You try to SSH into a server and get:
Permission denied (publickey,password).Or variations:
Permission denied (publickey).Permission denied (publickey,gssapi-keyex,gssapi-with-mic).user@server: Permission denied (publickey,password).The SSH server rejected your authentication. None of the authentication methods you offered (public key, password, or others) were accepted.
Why This Happens
SSH authentication is a negotiation. The client lists the credentials it has, the server lists the methods it accepts, and the two sides walk through each option in order. When the negotiation finishes without a match, the server emits “Permission denied” and includes the methods it was willing to try in parentheses. That list is the most important hint in the error: it tells you which authentication paths the server is even open to. If password is missing from the list, no password will ever succeed regardless of what you type.
The next layer of complexity is that “authentication failed” can mean very different things: the key was offered but not in authorized_keys, the key was offered but uses an algorithm the server has disabled, the key file had wrong permissions and was silently skipped, or the username does not exist on the server at all. The client cannot tell you which of these happened, because exposing that information would help attackers. The only reliable way to find out is to enable verbose logging on the client (ssh -vvv) and check the server’s auth log (/var/log/auth.log or journalctl -u sshd) side by side.
Common causes:
- Wrong SSH key. The key you are offering does not match any authorized key on the server.
- Wrong username. You are connecting as the wrong user.
- SSH key not added to the agent. Your key exists but the SSH agent is not using it.
- Incorrect file permissions. The
~/.sshdirectory or key files have wrong permissions. - Password authentication disabled. The server only accepts key-based authentication.
- Key not authorized on the server. Your public key is not in
~/.ssh/authorized_keys. - Server configuration issue.
sshd_configrestricts which users or keys can connect.
Platform and Environment Differences
Which client you use, which OpenSSH version is installed, and where your home directory lives all change how SSH negotiates authentication. The same key that connects from macOS may be rejected from a fresh RHEL 9 box because of a small algorithm policy change.
OpenSSH 8.7 and newer (RHEL 9, Ubuntu 22.04+, Fedora 36+) disabled RSA signatures using SHA-1 (ssh-rsa) by default. Older keys generated with ssh-keygen -t rsa still exist, but the server refuses them because the signature algorithm is considered weak. The client lists the key in -v output and the server logs “userauth_pubkey: signature algorithm ssh-rsa not in PubkeyAcceptedAlgorithms.” Fix it by regenerating with ed25519, or by adding PubkeyAcceptedAlgorithms +ssh-rsa to ~/.ssh/config for legacy servers you cannot upgrade.
Windows clients come in two flavors. The built-in OpenSSH (Settings then Apps then Optional features) uses the same key formats as Linux — ~/.ssh/id_ed25519, OpenSSH PRIVATE KEY headers, ~/.ssh/config at C:\Users\<you>\.ssh\config. PuTTY uses its own .ppk format, which is incompatible with OpenSSH. Convert with PuTTYgen (“Load” the .ppk, then “Conversions” then “Export OpenSSH key”). The .ppk is also what Pageant loads; native OpenSSH cannot consume it directly.
WSL2 introduces a third variant. The Linux side of WSL2 has its own ~/.ssh directory under \\wsl$\Ubuntu\home\<user>\.ssh, and key permissions on that mount are enforced by Linux rules even though the underlying storage is NTFS. Sharing keys between Windows and WSL2 usually means symlinking or copying the key into the WSL2 home and running chmod 600 inside the distro. Agent forwarding from Windows to WSL2 works via wsl-ssh-agent or by setting SSH_AUTH_SOCK to a relay socket — ssh-agent instances do not cross the boundary on their own.
macOS integrates ssh-agent with the Keychain. Adding UseKeychain yes and AddKeysToAgent yes to ~/.ssh/config makes the passphrase persist across reboots. Without these, every reboot drops cached keys and you fall back to passphrase prompts. macOS Sonoma deprecated the older Keychain integration flag (-K and -A on ssh-add); the supported flags are --apple-use-keychain and --apple-load-keychain.
Legacy UNIX (AIX, Solaris, older HP-UX) often ships OpenSSH versions that predate ed25519. Such servers reject ssh-ed25519 keys outright. Generate an ssh-rsa 4096-bit key (ssh-keygen -t rsa -b 4096) for these targets and keep your ed25519 key for everything modern.
Cloud-init defaults matter when troubleshooting cloud VMs. AWS Ubuntu AMIs default the user to ubuntu, Amazon Linux to ec2-user, Debian to admin, and DigitalOcean ships as root. Cloud-init reads the key uploaded through the console and writes it to ~/.ssh/authorized_keys for that single user. Connecting as root to an Ubuntu EC2 instance always fails because root login is disabled and no key was installed for root.
Fix 1: Check the Username
The most overlooked fix. Make sure you are connecting as the correct user:
ssh [email protected] # Ubuntu EC2
ssh [email protected] # Amazon Linux
ssh [email protected] # Root (if allowed)
ssh [email protected] # Debian
ssh [email protected] # Custom userCommon default users by platform:
| Platform | Default User |
|---|---|
| Ubuntu EC2 | ubuntu |
| Amazon Linux | ec2-user |
| Debian | admin |
| CentOS/RHEL | centos or ec2-user |
| Fedora | fedora |
| SUSE | ec2-user |
| macOS | Your macOS username |
| DigitalOcean | root |
If you SSH without specifying a user (ssh server.example.com), SSH uses your local username, which might not exist on the server.
Fix 2: Specify the Correct SSH Key
If you have multiple SSH keys, specify which one to use:
ssh -i ~/.ssh/my-key.pem [email protected]Check which keys are available:
ls -la ~/.ssh/Common key files:
id_rsa/id_rsa.pub— RSA key pairid_ed25519/id_ed25519.pub— Ed25519 key pair (recommended)*.pem— AWS EC2 key pairs
Check which key SSH is trying to use:
ssh -v [email protected]Look for lines like:
debug1: Offering public key: /home/user/.ssh/id_ed25519
debug1: Server accepts key: /home/user/.ssh/id_ed25519Or:
debug1: Trying private key: /home/user/.ssh/id_rsa
debug1: No more authentication methods to try.If none of your keys are accepted, the correct key is not being offered.
Pro Tip: Use
~/.ssh/configto map hostnames to keys:Host myserver HostName server.example.com User ubuntu IdentityFile ~/.ssh/my-key.pemThen simply:
ssh myserver
Fix 3: Add Your Key to the SSH Agent
The SSH agent manages your keys. If your key is not loaded, SSH does not offer it:
# Start the agent (if not running)
eval "$(ssh-agent -s)"
# Add your key
ssh-add ~/.ssh/id_ed25519
# List loaded keys
ssh-add -lFor AWS .pem keys:
chmod 400 ~/.ssh/my-key.pem
ssh-add ~/.ssh/my-key.pemmacOS Keychain:
ssh-add --apple-use-keychain ~/.ssh/id_ed25519Add to ~/.ssh/config to persist across reboots:
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519Fix 4: Fix File Permissions
SSH is strict about permissions. Wrong permissions cause silent authentication failure:
# Fix directory permissions
chmod 700 ~/.ssh
# Fix private key permissions
chmod 600 ~/.ssh/id_ed25519
chmod 600 ~/.ssh/id_rsa
chmod 400 ~/.ssh/*.pem
# Fix public key permissions
chmod 644 ~/.ssh/id_ed25519.pub
# Fix authorized_keys permissions
chmod 600 ~/.ssh/authorized_keys
# Fix ownership
chown -R $(whoami):$(whoami) ~/.sshOn the server side too:
chmod 700 /home/user/.ssh
chmod 600 /home/user/.ssh/authorized_keys
chown -R user:user /home/user/.sshIf the .ssh directory or key files are world-readable, SSH refuses to use them. This is a security feature.
Common Mistake: Setting permissions to
777or666on SSH files. SSH intentionally rejects keys with overly permissive permissions. Private keys must be600(owner read/write only) and the.sshdirectory must be700.
If your SSH-into-Docker-container scenario fails with a similar message, see Fix: Docker permission denied socket.
Fix 5: Add Your Public Key to the Server
Your public key must be in ~/.ssh/authorized_keys on the server:
Copy your public key to the server:
ssh-copy-id [email protected]If ssh-copy-id is not available or password auth is disabled, copy manually:
# On your local machine
cat ~/.ssh/id_ed25519.pub
# Copy the output
# On the server (via console access)
mkdir -p ~/.ssh
echo "ssh-ed25519 AAAA... [email protected]" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.sshFor cloud instances: Upload your public key through the cloud provider’s console:
- AWS: Key pairs in EC2 console
- GCP: Metadata → SSH Keys
- Azure: Reset password/SSH key in VM settings
- DigitalOcean: Settings → Security → SSH Keys
Fix 6: Check Server SSH Configuration
The server’s /etc/ssh/sshd_config controls authentication methods:
# On the server
sudo grep -E "PasswordAuthentication|PubkeyAuthentication|PermitRootLogin|AuthorizedKeysFile" /etc/ssh/sshd_configEnable public key authentication:
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keysEnable password authentication (if needed):
PasswordAuthentication yesAllow root login (not recommended for production):
PermitRootLogin yesAfter changes, restart SSH:
sudo systemctl restart sshdWarning: Be careful editing sshd_config while connected via SSH. A misconfiguration can lock you out. Always keep a second SSH session or console access open while testing changes.
Fix 7: Generate a New SSH Key Pair
If you do not have an SSH key or need a new one:
ssh-keygen -t ed25519 -C "[email protected]"Follow the prompts. The key pair is saved to ~/.ssh/id_ed25519 (private) and ~/.ssh/id_ed25519.pub (public).
For systems that require RSA:
ssh-keygen -t rsa -b 4096 -C "[email protected]"Then add the public key to the server (Fix 5).
For Git-specific SSH key issues, see Fix: git permission denied publickey.
Fix 8: Debug SSH Connection
Use verbose mode to see exactly what happens during connection:
ssh -vvv [email protected]Key things to look for in the output:
debug1: Authentications that can continue: publickey,passwordThis shows which methods the server accepts.
debug1: Offering public key: /home/user/.ssh/id_ed25519
debug1: Authentications that can continue: publickey,passwordThe key was offered but not accepted — wrong key or not in authorized_keys.
debug1: No more authentication methods to try.All methods exhausted — none worked.
Check the server logs:
sudo journalctl -u sshd -f
# or
sudo tail -f /var/log/auth.logServer logs show why authentication failed (wrong key, permission issues, user not allowed).
Still Not Working?
Check for SELinux. On RHEL/CentOS, SELinux can block SSH even with correct permissions:
restorecon -R ~/.sshCheck for firewall rules. If you cannot connect at all, it might be a network issue rather than authentication. See Fix: SSH connection timed out.
Check for AllowUsers/AllowGroups. sshd_config might restrict which users can SSH:
AllowUsers ubuntu admin
AllowGroups ssh-usersIf your user is not in the list, authentication fails even with correct credentials.
Check for PAM issues. PAM (Pluggable Authentication Modules) might impose additional restrictions:
grep -r "pam" /etc/ssh/sshd_configCheck for fail2ban. If you tried too many failed logins, fail2ban might have banned your IP:
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip YOUR_IPTry from a different network. Some networks (corporate, public WiFi) block SSH port 22. Try connecting on port 443 if the server supports it, or use a VPN.
Check PubkeyAcceptedAlgorithms on modern servers. OpenSSH 8.7+ removed ssh-rsa from the default algorithm list. If your client offers an RSA key signed with SHA-1, the server logs “userauth_pubkey: signature algorithm ssh-rsa not in PubkeyAcceptedAlgorithms” and rejects it silently from the client’s perspective. Either regenerate as ed25519 with ssh-keygen -t ed25519, or add PubkeyAcceptedAlgorithms +ssh-rsa to the relevant Host block in ~/.ssh/config while you migrate.
Check WSL2 agent forwarding. If you forwarded an agent from Windows into WSL2 and the socket points at a stale or missing path, every key offer falls through. Run ssh-add -l inside WSL2 — if it errors with “Could not open a connection to your authentication agent,” SSH_AUTH_SOCK is unset or wrong. Restart the relay (wsl-ssh-agent or your chosen bridge) and re-export SSH_AUTH_SOCK.
Check for home-directory ACLs on macOS. On a Mac that has been migrated from Time Machine or upgraded across major versions, ~/.ssh can end up with extended ACLs that look fine to ls -l but trigger “Bad owner or permissions on ~/.ssh.” Inspect with ls -le ~/.ssh and clear extra entries with chmod -N ~/.ssh ~/.ssh/*. For permission denied errors in bash scripts (not SSH), see Fix: bash permission denied.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: SSH Connection Timed Out or Connection Refused
How to fix SSH errors like 'Connection timed out', 'Connection refused', or 'No route to host' when connecting to remote servers.
Fix: Valkey Not Working — Redis Client Compatibility, ACL, Cluster Mode, and Migration
How to fix Valkey errors — client connection refused, RESP protocol compatibility, ACL user setup, cluster slot reshard, persistence config (RDB/AOF), TLS, Sentinel mode, and migrating from Redis.
Fix: Docker Container Keeps Restarting
How to fix a Docker container that keeps restarting — reading exit codes, debugging CrashLoopBackOff, fixing entrypoint errors, missing env vars, out-of-memory kills, and restart policy misconfiguration.
Fix: Linux OOM Killer Killing Processes (Out of Memory)
How to fix Linux OOM killer terminating processes — reading oom_kill logs, adjusting oom_score_adj, adding swap, tuning vm.overcommit, and preventing memory leaks.