
How to Fix Permission Denied Publickey SSH Connection Error
One of the most common blockers when pushing code to GitHub or logging into a remote Linux virtual machine is the dreaded SSH connection failure: "Permission denied (publickey).".
This error indicates that the SSH protocol handshake failed. The remote server requested a secure public key credential for authentication, but your local computer failed to present a matching private key.
In this guide, we will examine why SSH authentication fails, verify your local key configurations, generate modern secure keys, configure the SSH agent, and debug connections step-by-step.
Why Does SSH Authentication Fail?
When you connect to a server via SSH (e.g., executing ssh user@server or pushing code via git push), a cryptographic exchange occurs:
- The server reads the username and looks for authorized public keys stored in its local configuration (such as the
~/.ssh/authorized_keysfile or your GitHub profile settings). - The server sends a encrypted challenge message to your local machine.
- Your local SSH client must decrypt this challenge using the corresponding private key stored locally.
If your local machine has no private key, has not loaded the key into the active memory agent, or the remote server lacks the matching public key, the authentication loop fails, raising the Permission denied error.
Step 1: Check for Existing SSH Keys
First, check if your local machine already has SSH keys generated:
# List files in your local SSH directory
ls -la ~/.sshLook for files with these names:
- Ed25519 (Recommended):
id_ed25519(private key) andid_ed25519.pub(public key). - RSA (Legacy):
id_rsaandid_rsa.pub.
If these files are missing, proceed to Step 2. If you already have these files, skip to Step 3.
Step 2: Generate a New SSH Key Pair
If you lack SSH keys, generate a new pair using the Ed25519 algorithm. Ed25519 is more secure and has better performance than legacy RSA:
ssh-keygen -t ed25519 -C "your_email@example.com"- When prompted to "Enter file in which to save the key", press
Enterto accept the default directory. - When prompted for a passphrase, either enter a secure passphrase for extra safety or press
Entertwice to leave it empty.
Step 3: Add Your Private Key to ssh-agent
The ssh-agent is a background helper program that keeps your decrypted private keys loaded in memory, preventing you from typing your passphrase continuously.
Start the agent:
eval "$(ssh-agent -s)"Add your newly created private key to the agent:
ssh-add ~/.ssh/id_ed25519Step 4: Configure the Public Key on GitHub or Servers
Now, copy the contents of your public key (the file ending in .pub). Never share or copy your private key.
# Display the public key contents to your terminal window
cat ~/.ssh/id_ed25519.pubCopy the entire output string, which starts with ssh-ed25519.
For GitHub / GitLab integrations:
- Navigate to GitHub Settings -> SSH and GPG Keys.
- Click New SSH Key.
- Give it a descriptive Title (e.g., "Work Laptop") and paste the copied string into the Key field.
For direct Linux servers logins:
Log into the remote server using password authentication and append your public key string to the authorized_keys file:
echo "YOUR_COPIED_PUBLIC_KEY_STRING" >> ~/.ssh/authorized_keys
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keysStep 5: Test and Debug the Connection
To verify that the configuration was successful, run a test connection:
# Test connection to GitHub
ssh -T git@github.comIf it succeeds, you will see a message: "Hi username! You've successfully authenticated...".
If it still fails, run the command in Verbose Mode by adding the -v flag. This prints the entire authentication sequence, highlighting exactly where it fails:
ssh -Tv git@github.comIn the verbose output, look for lines starting with debug1:. Search for lines like debug1: Authentications that can continue: publickey and trace which local private key files the client attempted to load.
Conclusion
SSH key issues are resolved by verifying the key handshake chain. By checking for keys in ~/.ssh/, generating modern secure Ed25519 keys using ssh-keygen, loading them into the active ssh-agent, adding the public key string to GitHub settings or authorized_keys servers files, and using ssh -v to trace handshakes, you can resolve connection permission issues.