"git@github.com: Permission denied (publickey)": come risolvere

GitHub non ha accettato nessuna chiave offerta dal tuo client SSH. Esegui ssh -vT git@github.com per vedere quali chiavi vengono offerte. Poi assicurati che la chiave sia quella aggiunta al tuo account GitHub, che sia caricata o indicata in ~/.ssh/config, e che ti colleghi come utente git. Non usare sudo git, che cerca le chiavi di root. Gli stessi controlli valgono per GitLab con ssh -T git@gitlab.com.

Aggiornata il . Il testo dell'errore di Git, ssh -G, core.sshCommand e i comandi git remote sono stati eseguiti con OpenSSH 10.3 e Git su macOS contro un server di prova locale con una chiave usa e getta.

Cosa vedi

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.

La prima riga è il vero errore, e viene da SSH. Le righe di Git compaiono anche per molti altri fallimenti, quindi non lasciare che ti mandino a guardare il repository.

Prova SSH senza Git

ssh -T git@github.com

Quando la chiave viene accettata, GitHub ti saluta e chiude la connessione. Lo stato di uscita è 1 anche in quel caso, perché GitHub non offre una shell:

Hi username! You've successfully authenticated, but GitHub does not provide shell access.
  • Ricevi Permission denied (publickey): segui le cause qui sotto.
  • Ricevi il saluto con un nome diverso da quello atteso: SSH sta usando la chiave di un altro account. Vedi la causa 3.
  • Ricevi il saluto con il nome giusto ma Git fallisce con Repository not found: il tuo account non ha accesso a quel repository, oppure l'URL è sbagliato.

Causa 1: non viene offerta nessuna chiave, o quella sbagliata

ssh -vT git@github.com 2>&1 | grep -E 'identity file|Offering|Authentications'

Una riga che finisce con type -1 significa che SSH non ha trovato quel file. SSH cerca nomi predefiniti come ~/.ssh/id_ed25519 e ~/.ssh/id_rsa. Senza nessuna riga Offering public key, non è stato provato nulla. Guarda cosa hai a disposizione:

ls -l ~/.ssh/
ssh-add -l

Se la tua chiave ha un altro nome di file, dillo a SSH in ~/.ssh/config:

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

Controlla il risultato senza collegarti:

ssh -G github.com | grep -E '^(user|identityfile|identitiesonly) '

Se non hai nessuna chiave, segui come aggiungere una chiave SSH a GitHub.

Causa 2: la chiave pubblica non è sul tuo account

Confronta i fingerprint, non l'aspetto della chiave:

ssh-keygen -lf ~/.ssh/id_ed25519.pub

Poi apri GitHub, Settings, SSH and GPG keys, e cerca lo stesso valore SHA256:. Se manca, aggiungi il contenuto del file .pub. Non incollare mai la chiave privata. Una chiave usata come deploy key su un repository non può essere aggiunta anche a un account.

Causa 3: l'account sbagliato

Con un account di lavoro e uno personale, vince la prima chiave che GitHub riconosce, anche se appartiene all'altro account. IdentitiesOnly yes, come mostrato sopra, limita SSH alla chiave che indichi. Per usare due account in parallelo, vedi più account GitHub.

Per un solo repository, puoi impostare direttamente una chiave:

git config core.sshCommand "ssh -i ~/.ssh/id_ed25519_work -o IdentitiesOnly=yes"

Causa 4: l'utente sbagliato nell'URL

L'utente è sempre git, non il tuo nome su GitHub:

git remote -v

Un remote SSH corretto inizia con git@github.com:. Se il tuo ha un altro nome utente, reimpostalo:

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

Causa 5: sudo

sudo git pull gira come root, quindi SSH cerca in /root/.ssh, e il tuo agent di solito è fuori portata. Correggi invece il proprietario della cartella ed esegui Git come te stesso:

sudo chown -R "$USER" /path/to/repo

Causa 6: la chiave non è caricata

Una chiave con passphrase, usata da un'app grafica o da uno script che non può chiederla, fallisce come se mancasse. Caricala:

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

Se stampa un errore, vedi Could not open a connection to your authentication agent.

Su Mac l'agent dimentica la chiave dopo un riavvio. Salva la passphrase nel Portachiavi una volta sola:

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

Poi aggiungi queste due righe al blocco Host github.com di ~/.ssh/config, così SSH carica la chiave da solo:

  AddKeysToAgent yes
  UseKeychain yes

Altre cose da provare

  • Permessi della chiave: se l'output cita UNPROTECTED PRIVATE KEY FILE, vedi questa soluzione.
  • Troppe chiavi nell'agent: vedi Too many authentication failures.
  • In CI: usa una deploy key o un token del tuo sistema di CI. Le chiavi personali non ci appartengono.
  • Per andare avanti in fretta, HTTPS con un token evita del tutto SSH: git remote set-url origin https://github.com/owner/repo.git.
  • Git su un server remoto: inoltra la chiave con l'agent invece di copiarla lì, dopo aver letto i rischi dell'agent forwarding SSH.

Domande

Perché Git dice Could not read from remote repository?

È la riga generica di Git dopo un errore di SSH. La causa vera è la riga sopra, qui Permission denied (publickey): GitHub non ha accettato nessuna chiave offerta da SSH.

Come vedo quale chiave SSH manda a GitHub?

Esegui ssh -vT git@github.com e leggi le righe Offering public key. ssh-add -l elenca le chiavi caricate nell'agent.

Perché git pull fallisce solo con sudo?

sudo lavora come root, quindi SSH legge /root/.ssh e di solito non raggiunge il tuo agent. Esegui Git come il tuo utente e correggi invece il proprietario della cartella.

Fonti

Altro in Messaggi di errore

Tutte le guide