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?

If you’re seeing this error

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

You’re in the right place — the fix is below.

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 76 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

Always fixable

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 fixable

Git says 'Repository not found' but the URL is definitely right — why?

On a private repository, GitHub returns 'not found' rather than 'access denied' — so this usually means you are authenticated as the wrong account, not that the repository is missing. Check who you are with ssh -T git@github.com, and clear any stale credential your helper is replaying.

Read the fix →
Always fixable

git commit fails with 'error: gpg failed to sign the data' — how do I fix commit signing?

Test the signing outside Git first: echo test | gpg --clearsign. 'Inappropriate ioctl for device' means the passphrase prompt has nowhere to draw — add export GPG_TTY=$(tty) to your shell profile. 'No secret key' means user.signingkey does not match a key you hold. If you just want to commit right now, git commit --no-gpg-sign gets you through.

Read the fix →
Always fixable

How 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 →
← All Git Rescue guides