Fix 'Permission denied (publickey)' with Git and SSH
git clone or push fails with Permission denied (publickey) — how do I fix my SSH key?
Short answer
The server didn't accept any key your SSH client offered. Either you have no key, the key isn't loaded into the agent, or its public half was never added to your account. Run ssh -T git@github.com to see exactly which keys are being tried.
ssh -T git@github.com
Tests your SSH setup and names the exact problem
Does this match your situation?
- 'git@github.com: Permission denied (publickey).'
- 'fatal: Could not read from remote repository.'
- Cloning over HTTPS works but SSH doesn't.
- It worked on your old machine but not the new one.
Step-by-step fix
Test the connection directly
This bypasses Git entirely and tells you whether SSH authentication itself works. A successful result greets you by username; anything else is the real error.
step 1ssh -T git@github.com # success: "Hi username! You've successfully authenticated..." # see exactly which keys get offered: ssh -vT git@github.comCheck whether you actually have a key
A new machine has no keys at all. If the directory is empty or missing, generate one — ed25519 is the modern default.
step 2ls -al ~/.ssh # nothing there? create one: ssh-keygen -t ed25519 -C "you@example.com"Show the PowerShell (Windows) version
PowerShell (Windows)Get-ChildItem $env:USERPROFILE\.ssh ssh-keygen -t ed25519 -C "you@example.com"Load the key into the SSH agent
A key on disk that the agent doesn't know about is never offered. On Windows the agent service is disabled by default and has to be started first.
step 3eval "$(ssh-agent -s)" ssh-add ~/.ssh/id_ed25519 ssh-add -l # confirm it is loadedShow the PowerShell (Windows, as Admin) version
PowerShell (Windows, as Admin)Set-Service ssh-agent -StartupType Automatic Start-Service ssh-agent ssh-add $env:USERPROFILE\.ssh\id_ed25519 ssh-add -lAdd the PUBLIC key to your account
Copy the contents of the .pub file — never the private key, which has no extension — and paste it into your host's SSH keys settings.
step 4cat ~/.ssh/id_ed25519.pub # paste at: # GitHub -> github.com/settings/keys # GitLab -> gitlab.com/-/user_settings/ssh_keysOnly ever share the .pub file. The file without .pub is your private key and must never leave the machine.
Fix permissions if SSH still refuses
OpenSSH ignores keys whose files are readable by other users. On Unix-like systems this is a very common cause after copying keys between machines.
step 5chmod 700 ~/.ssh chmod 600 ~/.ssh/id_ed25519 chmod 644 ~/.ssh/id_ed25519.pub
Why this works
SSH public-key authentication works by the client proving it holds the private key matching a public key the server already trusts. Three separate things must line up: the key pair must exist, the client must actually offer that key (which usually means the agent has it loaded), and the server must have the public half on your account. 'Permission denied (publickey)' means the handshake finished without any offered key matching — which is why the verbose output, showing exactly which keys were tried, is the fastest diagnosis.
If that didn’t work
- Multiple accounts or hosts? Add a Host block in ~/.ssh/config with an explicit IdentityFile.
- Corporate network blocking port 22? Use ssh.github.com on port 443 via ~/.ssh/config.
- For an organisation repo, the key may need SSO authorisation in your account settings.
- Confirm the remote URL is the SSH form (git@host:user/repo.git), not HTTPS.
How to stop it happening again
- Back up ~/.ssh securely, or accept generating a fresh key per machine (which is arguably better practice).
- Add every machine's public key to your account as you set it up.
- Use ~/.ssh/config to pin the right key per host so nothing depends on agent ordering.
Commands used in this guide
Still stuck?
Search the full command reference and every other rescue guide — there are 56 of them, covering everything from detached HEAD to force-push disasters.
Browse all guides →Frequently asked questions
What does 'Permission denied (publickey)' mean?
The SSH server rejected every key your client offered. Either no key was offered at all, or the ones offered aren't registered on your account. It's an authentication failure, not a repository permission problem.
Which file do I paste into GitHub — id_ed25519 or id_ed25519.pub?
The .pub one, always. That's the public half and is safe to share. The file without .pub is your private key; if it ever leaves your machine, delete the key pair and generate a new one.
How do I use different SSH keys for work and personal accounts?
Create a ~/.ssh/config with a Host block per identity — for example Host github-work with its own HostName github.com and IdentityFile — then use git@github-work:org/repo.git as the remote URL so the right key is always chosen.
Related rescue guides
Git keeps saying authentication failed even though my password is correct — why?
GitHub stopped accepting account passwords over HTTPS in August 2021. You need a personal access token in place of the password, or better, switch the remote to SSH. If it worked yesterday, a cached old credential is usually the culprit — clear it and re-authenticate.
Read the fix →Always fixableHow do I make Git remember my credentials?
Configure a credential helper that stores the token in your OS keychain, or switch to SSH keys and skip credentials entirely. Avoid the `store` helper — it writes your token to a plaintext file.
Read the fix →Always fixableHow do I change the remote URL of a Git repository?
git remote set-url origin <new-url> repoints an existing remote. It's a purely local change — nothing on either server is touched — so it's the safe way to switch between HTTPS and SSH, move to a new host, or fix a URL after renaming the repository.
Read the fix →Always fixableCloning takes forever — how do I clone a big repo faster?
Use --filter=blob:none for a partial clone that fetches file contents lazily, and add sparse-checkout to materialise only the directories you need. --depth 1 is fastest of all but gives you no usable history.
Read the fix →