Permission denied (publickey)

Fix 'Permission denied (publickey)' When Git Pushes to GitHub

SSH is rejecting your key. Usually it's a missing or unloaded key in ssh-agent, a wrong remote URL, or a key GitHub doesn't know about.

You ran git push and got hit with 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.

The repo exists. Your access is fine. The problem is SSH — it either can't find a key it recognizes, isn't offering the right one, or is offering one GitHub has never seen. Work through these in order. Don't skip.

Cause 1: ssh-agent isn't running your key (this is the one, 80% of the time)

You generated a key. You added it to GitHub. Then you rebooted, or opened a new terminal, and now nothing works. That's because the key isn't loaded into ssh-agent anymore. The agent is per-session on Linux, and on macOS it may or may not be persistent depending on your setup.

Check what the agent has:

ssh-add -l

If you see The agent has no identities., that's your problem. Add the key:

ssh-add ~/.ssh/id_ed25519

Swap in id_rsa if that's what you generated. Then verify:

ssh -T git@github.com

You want Hi username! You've successfully authenticated.... If you see that, push away.

On macOS with Keychain, make it persistent so you stop doing this every reboot:

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

Older macOS uses -K instead of --apple-use-keychain. And you'll want this in ~/.ssh/config:

Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519

On Linux, add the same AddKeysToAgent yes line and you're done. Don't bother with ssh-agent startup scripts from 2011 — modern distros handle this via systemd user units or your desktop session.

Cause 2: your remote URL is HTTPS, not SSH

This one trips people because the error looks identical. If your remote is https://github.com/user/repo.git, Git uses HTTPS auth, not SSH — and you'd normally get a credentials prompt, not a publickey error. But if you have a stale credential helper or SSH URL mismatch somewhere (submodules, deploy keys), you get the same wall.

Check:

git remote -v

If it shows https://, switch to SSH:

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

Then git push again. This is the fix when your key is fine but Git is talking the wrong protocol the whole time.

Submodules bite here too. A repo cloned via HTTPS can pull submodules over HTTPS even when your main remote is SSH. Fix each one with git submodule set-url or just edit .gitmodules and re-run git submodule sync.

Cause 3: GitHub doesn't have your public key (or you're offering the wrong one)

If ssh-add -l shows your key loaded, the remote is SSH, and you still get Permission denied, then GitHub doesn't recognize the key you're sending. Two reasons: you never uploaded it, or you have several keys and SSH is offering the wrong one first.

Run with verbosity to see exactly what's happening:

ssh -vT git@github.com

Watch the Offering public key: lines. If GitHub replies Authentications that can continue: publickey after each one and then closes, none of those keys are registered on your account.

Copy the public key (the .pub, never the private one) and paste it into GitHub under Settings → SSH and GPG keys → New SSH key:

cat ~/.ssh/id_ed25519.pub

If you have multiple keys (work + personal, for instance), tell SSH which to use per host in ~/.ssh/config:

Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_work_ed25519
  IdentitiesOnly yes

Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_personal_ed25519
  IdentitiesOnly yes

Then your remotes become git@github-work:org/repo.git. The IdentitiesOnly yes line matters — without it, SSH offers every key it can find and GitHub locks you out after too many failed attempts on the wrong one.

Quick sanity check: your private key file permissions must be 600. If they're world-readable, SSH refuses to use the key at all. chmod 600 ~/.ssh/id_ed25519 and re-test.

Quick reference

SymptomCauseFix
ssh-add -l says no identities Key not loaded in agent ssh-add ~/.ssh/id_ed25519
git remote -v shows https:// Wrong remote URL for SSH auth git remote set-url origin git@github.com:user/repo.git
ssh -vT shows key offered but rejected Key not on GitHub, or wrong key offered Upload .pub, set IdentitiesOnly yes in ~/.ssh/config
SSH ignores your key entirely Bad file permissions chmod 600 ~/.ssh/id_ed25519
Works in one terminal, not another Agent not shared across sessions Enable AddKeysToAgent yes and Keychain on macOS

Nine times out of ten it's the agent. Test with ssh -T git@github.com before you touch anything else — that single command tells you whether SSH auth works end to end, independent of Git.

Related Errors in Programming & Dev Tools
Error: Cannot find module Node.js require absolute path fails: 3 common fixes E0499 E0499: Fix Rust's 'cannot borrow as mutable more than once' in iterator loops SIGSEGV Segfault After scanf? You Forgot the Pointer Address remote origin already exists Git remote origin already exists: fix it in 30 seconds

Was this solution helpful?

EP
Erropedia Team
Tech Support Editors
The Erropedia editorial team researches and documents real-world tech errors from across Windows, Linux, macOS, networking, databases, cloud platforms, and more. Every solution is reviewed for accuracy and updated as software and systems evolve.