Push & pull problemsAlways fixable

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.

quick fix
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

  1. 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 1
    ssh -T git@github.com
    # success: "Hi username! You've successfully authenticated..."
    
    # see exactly which keys get offered:
    ssh -vT git@github.com
    
  2. Check 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 2
    ls -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"
    
  3. 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 3
    eval "$(ssh-agent -s)"
    ssh-add ~/.ssh/id_ed25519
    ssh-add -l          # confirm it is loaded
    
    Show 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 -l
    
  4. Add 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 4
    cat ~/.ssh/id_ed25519.pub
    # paste at:
    #   GitHub -> github.com/settings/keys
    #   GitLab -> gitlab.com/-/user_settings/ssh_keys
    

    Only ever share the .pub file. The file without .pub is your private key and must never leave the machine.

  5. 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 5
    chmod 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

git credential / credential.helper

Stop Git asking for your username and password on every push.

git remote

Manage the named URLs your repository syncs with.

git clone

Copy a remote repository, its full history and its branches, onto your machine.

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

← All Git Rescue guides