← Back to DevBytes

Fix Git 'Permission denied (publickey)' Error

Understanding the 'Permission denied (publickey)' Error

When you attempt to push, pull, or clone a Git repository over SSH and see the dreaded Permission denied (publickey) message, it means the SSH client was unable to authenticate with the remote server using your public key. The full error typically looks like this:

git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

This error occurs because SSH authentication relies on a cryptographic key pair — a private key stored locally on your machine and a corresponding public key that you register with the remote Git service (GitHub, GitLab, Bitbucket, or a self-hosted server). If any link in this chain is missing or misconfigured, authentication fails and Git halts the operation.

Why This Error Matters

SSH-based authentication is the most common and secure method for interacting with remote Git repositories. When it breaks, developers lose the ability to push code, deploy applications, or collaborate with team members. In production environments, CI/CD pipelines that rely on SSH to fetch dependencies or deploy builds will fail entirely. Understanding how to diagnose and fix this error is a fundamental skill that every developer should have — it saves hours of frustration and ensures uninterrupted workflow.

Step 1: Diagnose the Root Cause

🚀 Deploy your AI agent in 10 minutes

Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.

Try it free →

Before applying fixes, determine exactly where the problem lies. Run the following diagnostic command to test your SSH connection to the remote host:

ssh -T git@github.com

Replace github.com with your Git provider's hostname (e.g., gitlab.com, bitbucket.org, or your company's Git server). The -T flag disables pseudo-terminal allocation, which is required for services that don't provide a shell. A successful connection returns a message like:

Hi username! You've successfully authenticated, but GitHub does not provide shell access.

If you see Permission denied (publickey), the problem is confirmed. Next, check whether your SSH agent is running and has your key loaded:

ssh-add -l

If the agent reports The agent has no identities or Could not open a connection to your authentication agent, you've found your culprit. If identities are listed but the connection still fails, the public key likely hasn't been added to your remote account, or the key permissions are incorrect.

List Your Existing Keys

Check which SSH keys exist on your local machine:

ls -la ~/.ssh/

Look for files named id_rsa, id_ed25519, id_ecdsa, or custom-named keys. The public key files end with .pub. If the directory is empty or lacks a key pair, you need to generate one.

Step 2: Generate a New SSH Key Pair

If you don't have an existing key or want to create a dedicated key for Git operations, generate one using the Ed25519 algorithm (preferred for its speed and security) or RSA as a fallback:

# Recommended: Ed25519
ssh-keygen -t ed25519 -C "your_email@example.com"

# Fallback for older systems that don't support Ed25519
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

The -C flag adds a comment (usually your email) to help identify the key's purpose. When prompted for a file path, press Enter to accept the default location (~/.ssh/id_ed25519 or ~/.ssh/id_rsa). You'll be asked to enter a passphrase — this adds an extra layer of security. Even if you leave it empty, the key will work, but using a strong passphrase is strongly recommended.

The output confirms where the key was saved and displays the key's fingerprint and randomart image:

Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:abc123def456ghi789... your_email@example.com

Step 3: Add Your SSH Key to the SSH Agent

The SSH agent manages your private keys in memory so you don't need to enter the passphrase repeatedly. Start the agent and add your key:

# Start the SSH agent (if not already running)
eval "$(ssh-agent -s)"

# Add your private key to the agent
ssh-add ~/.ssh/id_ed25519

If you used a custom filename, specify that path instead. On macOS, the agent typically runs automatically. On Linux, you may need to add the eval line to your shell profile (~/.bashrc, ~/.zshrc) so the agent starts on login. On Windows with Git Bash or WSL, the same commands apply.

Persisting the SSH Agent Across Sessions (Linux/macOS)

Add these lines to your ~/.bashrc or ~/.zshrc to ensure the agent runs and loads your key automatically:

if [ -z "$SSH_AUTH_SOCK" ]; then
  eval "$(ssh-agent -s)"
  ssh-add ~/.ssh/id_ed25519 2>/dev/null
fi

On macOS, you can also use the --apple-use-keychain flag to store the passphrase in the Keychain:

ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Step 4: Add Your Public Key to the Remote Git Service

Copy the contents of your public key file to the clipboard:

# On Linux/macOS
cat ~/.ssh/id_ed25519.pub

# On Windows (Command Prompt or PowerShell)
type ~/.ssh/id_ed25519.pub

# Alternatively, use a clipboard command
# macOS:
pbcopy < ~/.ssh/id_ed25519.pub
# Linux (requires xclip):
xclip -selection clipboard < ~/.ssh/id_ed25519.pub
# Windows PowerShell:
Get-Content ~/.ssh/id_ed25519.pub | clip

Now navigate to your Git provider's SSH key settings page and paste the entire key, including the ssh-ed25519 prefix and the trailing comment:

Give the key a descriptive title (e.g., "Work Laptop - January 2025") so you can identify it later. After adding the key, test the connection again:

ssh -T git@github.com

You should see the success message confirming authentication. If prompted to accept the host's fingerprint, type yes — this adds the host to your ~/.ssh/known_hosts file and only happens once per host.

Step 5: Handle Multiple SSH Keys

Many developers maintain separate SSH keys for different purposes (personal GitHub, work GitLab, deployment servers). The SSH client doesn't automatically know which key to use for which host. To solve this, create or edit the SSH configuration file:

# Create or open the SSH config file
nano ~/.ssh/config

Add host-specific entries that map identities to hostnames:

# Personal GitHub account
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_personal
    IdentitiesOnly yes

# Work GitLab account
Host gitlab.work.com
    HostName gitlab.work.com
    User git
    IdentityFile ~/.ssh/id_ed25519_work
    IdentitiesOnly yes

# Self-hosted server on non-standard port
Host myserver
    HostName myserver.example.com
    Port 2222
    User deploy
    IdentityFile ~/.ssh/id_rsa_server

The IdentitiesOnly yes directive ensures SSH only uses the specified key and doesn't try all available keys sequentially — this prevents the server from rejecting you after too many failed attempts. After saving the config, test each host individually:

ssh -T git@github.com
ssh -T git@gitlab.work.com

Step 6: Fix Common File Permission Issues

SSH is extremely strict about file permissions. If your private key or the ~/.ssh directory has overly permissive access rights, SSH will refuse to use the key — often with a different but related error message. Set the correct permissions:

# Set ~/.ssh directory permissions to 700 (read/write/execute for owner only)
chmod 700 ~/.ssh

# Set private key permissions to 600 (read/write for owner only)
chmod 600 ~/.ssh/id_ed25519

# Set public key permissions to 644 (readable by all, writable by owner)
chmod 644 ~/.ssh/id_ed25519.pub

# Ensure the authorized_keys file (if you use it) has correct permissions
chmod 600 ~/.ssh/authorized_keys

# The known_hosts file should be 644
chmod 644 ~/.ssh/known_hosts

These commands apply to Linux and macOS. On Windows, the OpenSSH client enforces similar restrictions, but the permission model differs — ensure your .ssh directory is stored in a location only your user account can access (typically C:\Users\YourName\.ssh).

Step 7: Verify the Remote URL Uses SSH, Not HTTPS

Sometimes the error appears because the repository's remote URL is configured to use HTTPS instead of SSH. Check the remote URL:

git remote -v

SSH URLs follow the format git@github.com:username/repo.git, while HTTPS URLs look like https://github.com/username/repo.git. If you see an HTTPS URL and want to switch to SSH:

git remote set-url origin git@github.com:username/repo.git

Replace origin with the remote name if different, and substitute the correct hostname, username, and repository path. After changing the URL, test with a fetch:

git fetch origin

Troubleshooting Edge Cases

Agent Forwarding Issues

If you're SSHing into a remote server and trying to run Git commands from there (a common pattern for deployment), you need agent forwarding. Add this to your ~/.ssh/config:

Host myserver
    ForwardAgent yes

Then ensure your local agent has the key loaded and you connect with ssh -A (or rely on the config). On the remote server, run ssh-add -l to confirm the forwarded key is visible.

RSA Key Rejection by Modern Servers

Some Git providers (including GitHub) have deprecated RSA keys using SHA-1 signatures. If you generated an RSA key with ssh-keygen -t rsa before 2022, you may encounter Permission denied even with a correctly configured key. Generate a new Ed25519 key or an RSA key with SHA-2 signatures:

ssh-keygen -t rsa -b 4096 -E sha2 -C "your_email@example.com"

Then upload the new public key to your provider and update your SSH config accordingly.

Corporate VPN or Proxy Interference

Corporate networks sometimes route SSH traffic through proxies that strip or alter authentication packets. If you're on a VPN and suddenly get the publickey error, try:

Debugging with Verbose Output

When all else fails, SSH's verbose mode reveals exactly where authentication breaks down:

ssh -vT git@github.com

Increase verbosity with -vv or -vvv for more detail. Look for lines like:

This output is invaluable for pinpointing whether the issue is a missing key, wrong key, or network-level problem.

Best Practices for SSH Key Management

Conclusion

The Git Permission denied (publickey) error is a gatekeeper moment — it signals a break in the SSH authentication chain that every developer must understand to work effectively. The fix almost always boils down to four steps: verify you have a key pair, ensure the SSH agent has your private key loaded, confirm the corresponding public key is registered with your Git provider, and check that file permissions and remote URLs are correct. By mastering the diagnostic commands and configuration techniques outlined here, you can resolve this error in minutes rather than hours and build a robust SSH key management practice that scales across personal projects, team workflows, and production deployments. Keep your keys secure, your config file organized, and your agent running — and you'll never stare at that permission denied message in frustration again.

🚀 Need a reliable AI agent for your project?

Deploy Hermes Agent in 10 minutes. Managed hosting, zero DevOps.

Get Started — $23.99/mo
← Back to all articles