Automatone
HomeAbout

Automatone

AI tools, dev workflows, and automation. No hype, just what works.

Pages

HomeBlogAboutPrivacyTerms

Connect

GitHubRSS Feed

© 2026 Automatone. All rights reserved.

Admin
  1. Home
  2. ›Troubleshooting
  3. ›Fix "Permission denied (publickey)" for Git over SSH

Fix "Permission denied (publickey)" for Git over SSH

Sanchez Kim
Sanchez Kim
AI Engineer · June 26, 2026 · 6 min read

A fast, ordered fix for the git@github.com: Permission denied (publickey) error over SSH. Start by reading the verbose ssh -vT output, then walk through key generation, loading the agent, adding the public key, remote URLs, permissions, and the port 443 fallback.

#git#ssh#github#troubleshooting#permission denied publickey#ssh-keygen#devops
Fix "Permission denied (publickey)" for Git over SSH

You ran git push and got this:

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

This is an authentication failure, not a network or repo-access problem. The server accepted the TCP connection fine — it just couldn't verify who you are, because SSH never presented a key it recognizes. Everything below is about getting the right key offered and accepted. Work through it in order; most people are fixed by step 3 or 4.

Read the verbose output first

Before changing anything, ask SSH what's actually happening:

ssh -vT git@github.com

The -v flag prints every step of the handshake. You don't need to understand all of it — just two things:

  • Lines like Trying private key: /Users/you/.ssh/id_ed25519 followed by nothing, and an identity file ... type -1, mean SSH found no usable key to offer. The -1 means the file doesn't exist.
  • A line like Offering public key: ... means a key is being sent. If the connection still fails after that, the key either isn't on your account or it's the wrong key.

Success looks like this:

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

That message is normal — GitHub doesn't give you a shell, it just confirms the key works. If you see it, your SSH auth is fine and the problem is somewhere else (wrong remote URL, mostly — jump to the remote-URL section).

Annotated SSH verbose output highlighting the key-offering lines

Check that a key exists and is loaded

Two commands tell you whether you even have a key, and whether the agent is holding it:

ls -al ~/.ssh                 # look for id_ed25519 and id_ed25519.pub (or id_rsa)
ssh-add -l -E sha256          # fingerprints currently loaded in the agent

If ssh-add -l prints The agent has no identities, the agent isn't holding your key. Start it and add the key:

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

If ls ~/.ssh shows no id_* files at all, you don't have a key yet. Make one.

Generate a key if you don't have one

Ed25519 is GitHub's recommended type for all new keys. Use it unless you're on an old system that genuinely can't handle it:

ssh-keygen -t ed25519 -C "your_email@example.com"

Only fall back to RSA (ssh-keygen -t rsa -b 4096) on legacy systems without Ed25519 support. Accept the default file location, set a passphrase if you want one, and then load it with ssh-add as shown above.

Add the public key to your account

This is the single most common cause. Generating a key does nothing on its own — GitHub has to know about the public half.

cat ~/.ssh/id_ed25519.pub     # copy this — the .pub file, never the private one

Paste it into GitHub under Settings → SSH and GPG keys → New SSH key. The private key (the file without .pub) never leaves your machine.

To be sure you added the right key, compare fingerprints. Run ssh-add -l -E sha256 and look at the SHA256 string for your loaded key, then check it against the fingerprint GitHub shows next to the key in settings. If your loaded key's fingerprint isn't on the account, that mismatch is your bug.

GitHub SSH and GPG keys settings page with a new key being added

Fix the remote URL and the git user

Every SSH connection to GitHub is made as the git user — not your username. The remote should look like git@github.com:OWNER/REPO.git. A frequent trap is cloning over HTTPS and then expecting SSH auth to kick in (or the reverse).

Check what you have, and switch it if needed:

git remote -v
git remote set-url origin git@github.com:OWNER/REPO.git

One more thing worth ruling out: don't run Git with sudo. Under sudo the agent and ~/.ssh belong to a different user, so your key is invisible and you get the same error.

Fix file permissions

SSH silently ignores private keys whose files are readable by others — no warning, just a refusal to use the key. If the basics look right but the key still isn't offered, tighten the modes:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519        # private key
chmod 644 ~/.ssh/id_ed25519.pub    # public key

Pin the right key with an SSH config

When you have several keys, SSH may offer the wrong one and give up before reaching yours. Force the choice in ~/.ssh/config:

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

IdentitiesOnly yes is the important line — it stops SSH from trying every key it can find and offering them in the wrong order.

On macOS, you can also keep the passphrase in the Keychain so you don't retype it and the key loads automatically:

Host *
  AddKeysToAgent yes
  UseKeychain yes

Then add the key with the Apple flag:

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

--apple-use-keychain and --apple-load-keychain replaced the old -K and -A flags in macOS 12 Monterey. UseKeychain is Apple's own option and isn't part of upstream OpenSSH, so don't copy it onto a Linux box.

Port 22 blocked? Go over 443

Corporate and campus networks often block outbound port 22, so SSH never reaches GitHub at all. Test whether the HTTPS port works:

ssh -T -p 443 git@ssh.github.com

Note the host: it's ssh.github.com, not github.com. If that authenticates, make it permanent in ~/.ssh/config:

Host github.com
  Hostname ssh.github.com
  Port 443
  User git

After this, your normal git@github.com:... remotes route over 443 without any further changes.

Symptom → fix

Symptom (from ssh -vT) Cause Fix
type -1, no key offered No key file exists ssh-keygen -t ed25519
Key file exists, agent empty Key not loaded ssh-add ~/.ssh/id_ed25519
Offering public key then denied Key not on account Add .pub in GitHub settings
Auth works but push fails Wrong remote URL / not git user git remote set-url origin git@github.com:...
Key ignored, no warning Permissions too open chmod 600 the private key
Connection times out Port 22 blocked Use ssh.github.com port 443

Other hosts

GitLab and Bitbucket throw the exact same Permission denied (publickey) message, and the logic is identical — only the place you paste the key and the test host change. For GitLab, test with ssh -T git@gitlab.com.

On Windows, OpenSSH runs the agent as a service rather than something you start by hand. Use Get-Service ssh-agent and Start-Service ssh-agent in PowerShell, and rely on Windows ACLs instead of chmod for key permissions.

References

  • GitHub Docs — Error: Permission denied (publickey)
  • GitHub Docs — Generating a new SSH key and adding it to the ssh-agent
  • GitHub Docs — Using SSH over the HTTPS port
  • Apple Technical Note TN2449 — OpenSSH updates in macOS

Related Posts

Fix "ModuleNotFoundError: No module named" in Python
Jun 24, 2026·6 min read

Fix "ModuleNotFoundError: No module named" in Python

Most ModuleNotFoundError cases aren't a missing package — they're an interpreter or environment mismatch. This guide gives you two diagnostic commands to pin down which of the six real causes you have, then the exact fix for each, plus a copy-paste cheat sheet.

Troubleshooting
Fix "CUDA out of memory" Errors in PyTorch
Jun 17, 2026·8 min read

Fix "CUDA out of memory" Errors in PyTorch

CUDA out of memory in PyTorch often fires while nvidia-smi still shows free VRAM, because the caching allocator needs a contiguous block, not just free space. This guide gives a copy-paste triage path from fastest fixes to fragmentation tuning, plus how to tell a real leak apart from fragmentation.

Troubleshooting

On this page

  • Read the verbose output first
  • Check that a key exists and is loaded
  • Generate a key if you don't have one
  • Add the public key to your account
  • Fix the remote URL and the git user
  • Fix file permissions
  • Pin the right key with an SSH config
  • Port 22 blocked? Go over 443
  • Symptom → fix
  • Other hosts
  • References