KhueApps
Home/DevOps/Fixing 'Permission denied (publickey)' for Git over SSH

Fixing 'Permission denied (publickey)' for Git over SSH

Last updated: October 06, 2025

Overview

The error "Permission denied (publickey)" means the SSH server rejected your authentication because it didn’t accept any public keys you offered. For Git (GitHub, GitLab, Bitbucket, or self-hosted), this typically stems from missing keys, wrong permissions, or an SSH client not offering the right key.

This guide shows how to quickly fix it, then diagnose deeper issues.

Quickstart (works on Linux, macOS, WSL, Windows OpenSSH)

  • Generate a key (ED25519 is fast and secure):
ssh-keygen -t ed25519 -C "[email protected]" -f ~/.ssh/id_ed25519
  • Start the agent and add your key:
# Linux/macOS/WSL
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

# Windows PowerShell (OpenSSH)
Start-Service ssh-agent
Get-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519
  • Copy the public key and add it to your Git hosting account:
# Print the public key (copy the whole line)
cat ~/.ssh/id_ed25519.pub
  • Test SSH:
ssh -T [email protected]   # or [email protected], [email protected], etc.
  • Use the SSH remote (not HTTPS):
git remote set-url origin [email protected]:org/repo.git

Minimal working example

Create a dedicated SSH config entry so the correct key is always used.

# ~/.ssh/config
Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
  AddKeysToAgent yes

Test the connection:

ssh -vT [email protected]

Clone using SSH:

git clone [email protected]:org/repo.git

If this works, the error should be gone for Git operations (fetch, pull, push).

Step-by-step diagnosis

  1. Check that a key exists
ls -l ~/.ssh
# Expect id_ed25519 and id_ed25519.pub (or id_rsa and id_rsa.pub)

If missing, generate a new key.

  1. Fix file and directory permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_* ~/.ssh/config
chmod 644 ~/.ssh/*.pub
  1. Ensure the key is loaded into ssh-agent
ssh-add -l            # lists loaded keys
ssh-add ~/.ssh/id_ed25519

On Windows, ensure the OpenSSH Authentication Agent service is running.

  1. Force the client to offer the right key Use a host block in ~/.ssh/config with IdentitiesOnly yes and IdentityFile pointing to your key (see Minimal working example). Then:
ssh -o IdentitiesOnly=yes -vT [email protected]
  1. Verify the Git remote uses SSH
git remote -v
# If it shows https://..., switch to ssh
git remote set-url origin [email protected]:org/repo.git
  1. Confirm the correct username and host
  • For hosted Git, User is always git.
  • For self-hosted, confirm the SSH host, port, and user.
ssh -p 22 -vT [email protected]

If using a non-standard port:

Host git.example.com
  Port 2222
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
  1. Validate the public key is registered server-side
  • Hosted Git: ensure the same public key appears in your account’s SSH keys.
  • Self-hosted: append the public key to ~/.ssh/authorized_keys on the Git server for the target user.
# On the server (for the git or repo user):
mkdir -p ~/.ssh && chmod 700 ~/.ssh
cat /tmp/your_key.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
  1. Inspect verbose output for clues
ssh -vvvT [email protected]

Look for lines like:

  • Offering public key: ~/.ssh/id_ed25519
  • Authentications that can continue: publickey
  • Permission denied (publickey) If your key isn’t offered, fix the config or agent.
  1. Check for key type restrictions Some servers block weak or outdated keys. Prefer ED25519 or RSA 4096.
ssh-keygen -t rsa -b 4096 -C "[email protected]" -f ~/.ssh/id_rsa

Update IdentityFile if you switch keys.

  1. Handle multiple identities If you have many keys loaded, the server may reject after too many attempts. Limit what’s offered per host with IdentitiesOnly yes and a specific IdentityFile.

Permissions reference

PathOwnerPermissions
~/.sshyou700
~/.ssh/authorized_keysyou600
~/.ssh/id_ed25519you600
~/.ssh/id_ed25519.pubyou644
~/.ssh/configyou600

Common pitfalls

  • Using HTTPS remote while testing SSH.
  • Wrong username (use git for hosted services).
  • Wrong key path or key not added to ssh-agent.
  • Too many keys offered; server rejects before the right one.
  • Key added to a different account than the one owning the repo.
  • Non-standard SSH port not reflected in config.
  • Home directory or .ssh directory owned by root (on servers) causing permission issues.

Performance notes

  • Prefer ED25519 keys: faster than RSA with strong security.
  • Enable connection multiplexing to speed repeated Git operations:
Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
  ControlMaster auto
  ControlPath ~/.ssh/cm-%r@%h:%p
  ControlPersist 10m
  • Limit identities per host with IdentitiesOnly yes to reduce round-trips.
  • Keep ssh-agent running so keys don’t need to be re-read for each Git command.

Example: multiple Git hosts

Host github.com
  User git
  HostName github.com
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes

Host gitlab.com
  User git
  HostName gitlab.com
  IdentityFile ~/.ssh/id_gitlab
  IdentitiesOnly yes

Map each host to the correct key to avoid mismatches.

Tiny FAQ

  • Q: Do I have to regenerate my key? A: Not usually. First try loading the existing key into ssh-agent and fixing permissions.

  • Q: Can I use the same key for multiple Git hosts? A: Yes. You can reuse one key or create separate keys per host for isolation.

  • Q: Why does ssh -T work but git push fails? A: Your Git remote might still be HTTPS. Switch it to the SSH URL.

  • Q: Is RSA still okay? A: Yes, use at least 4096 bits. ED25519 is preferred for speed and simplicity.

  • Q: How do I test a non-standard port? A: Use ssh -p <port> host or set Port in the matching Host block in ~/.ssh/config.

Series: Git

DevOps