"git@github.com: Permission denied (publickey)" : comment le corriger

GitHub n'a accepté aucune des clés proposées par votre client SSH. Exécutez ssh -vT git@github.com pour voir quelles clés sont proposées. Vérifiez ensuite que la clé est bien celle ajoutée à votre compte GitHub, qu'elle est chargée ou nommée dans ~/.ssh/config, et que vous vous connectez avec l'utilisateur git. N'utilisez pas sudo git, qui cherche les clés de root. Les mêmes vérifications valent pour GitLab avec ssh -T git@gitlab.com.

Mis à jour le . Le texte d'erreur de Git, ssh -G, core.sshCommand et les commandes git remote ont été exécutés avec OpenSSH 10.3 et Git sous macOS contre un serveur de test local avec une clé jetable.

Ce que vous voyez

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 première ligne est la vraie erreur, et elle vient de SSH. Les lignes de Git apparaissent aussi pour de nombreux autres échecs : ne les laissez donc pas vous envoyer regarder du côté du dépôt.

Tester SSH sans Git

ssh -T git@github.com

Quand la clé est acceptée, GitHub vous salue et ferme la connexion. Le code de sortie est 1 même dans ce cas, car GitHub ne propose pas de shell :

Hi username! You've successfully authenticated, but GitHub does not provide shell access.
  • Vous obtenez Permission denied (publickey) : suivez les causes ci-dessous.
  • Vous obtenez le message de bienvenue avec un autre nom que prévu : SSH utilise une clé d'un autre compte. Voir la cause 3.
  • Vous obtenez le message de bienvenue avec le bon nom mais Git échoue avec Repository not found : votre compte n'a pas accès à ce dépôt, ou l'URL est fausse.

Cause 1 : aucune clé, ou la mauvaise clé, est proposée

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

Une ligne se terminant par type -1 signifie que SSH n'a pas trouvé ce fichier. SSH cherche des noms par défaut comme ~/.ssh/id_ed25519 et ~/.ssh/id_rsa. Sans aucune ligne Offering public key, rien n'a été essayé. Voyez ce qui est disponible :

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

Si votre clé a un autre nom de fichier, indiquez-le à SSH dans ~/.ssh/config :

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

Vérifiez le résultat sans vous connecter :

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

Si vous n'avez aucune clé, suivez comment ajouter une clé SSH à GitHub.

Cause 2 : la clé publique n'est pas sur votre compte

Comparez les empreintes, pas l'apparence de la clé :

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

Ouvrez ensuite GitHub, Settings, SSH and GPG keys, et cherchez la même valeur SHA256:. Si elle manque, ajoutez le contenu du fichier .pub. Ne collez jamais la clé privée. Une clé utilisée comme deploy key sur un dépôt ne peut pas être ajoutée en plus à un compte.

Cause 3 : le mauvais compte

Avec un compte professionnel et un compte personnel, la première clé que GitHub reconnaît l'emporte, même si elle appartient à l'autre compte. IdentitiesOnly yes, comme ci-dessus, limite SSH à la clé que vous nommez. Pour utiliser deux comptes côte à côte, voir plusieurs comptes GitHub.

Pour un seul dépôt, vous pouvez définir une clé directement :

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

Cause 4 : le mauvais utilisateur dans l'URL

L'utilisateur est toujours git, pas votre nom GitHub :

git remote -v

Un remote SSH correct commence par git@github.com:. Si le vôtre a un autre nom d'utilisateur, redéfinissez-le :

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

Cause 5 : sudo

sudo git pull s'exécute en root : SSH cherche donc dans /root/.ssh, et votre agent est en général hors de portée. Corrigez plutôt le propriétaire du dossier, et exécutez Git sous votre propre compte :

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

Cause 6 : la clé n'est pas chargée

Une clé protégée par phrase secrète, utilisée par une application graphique ou un script qui ne peut rien demander, échoue comme si elle était absente. Chargez-la :

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

Si cela affiche une erreur, voir Could not open a connection to your authentication agent.

Sur Mac, l'agent oublie la clé après un redémarrage. Enregistrez une fois la phrase secrète dans le trousseau :

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

Ajoutez ensuite ces deux lignes au bloc Host github.com de ~/.ssh/config, pour que SSH charge la clé tout seul :

  AddKeysToAgent yes
  UseKeychain yes

Autres pistes

  • Permissions de la clé : si la sortie mentionne UNPROTECTED PRIVATE KEY FILE, voir cette solution.
  • Trop de clés dans l'agent : voir Too many authentication failures.
  • En CI : utilisez une deploy key ou un jeton de votre système de CI. Les clés personnelles n'y ont pas leur place.
  • Pour avancer vite, HTTPS avec un jeton évite complètement SSH : git remote set-url origin https://github.com/owner/repo.git.
  • Git sur un serveur distant : transmettez votre clé par l'agent au lieu de l'y copier, après avoir lu les risques de l'agent forwarding SSH.

Questions

Pourquoi Git affiche-t-il Could not read from remote repository ?

C'est la ligne générique de Git après un échec de SSH. La vraie cause est la ligne du dessus, ici Permission denied (publickey) : GitHub n'a accepté aucune des clés proposées par SSH.

Comment voir quelle clé SSH envoie à GitHub ?

Lancez ssh -vT git@github.com et lisez les lignes Offering public key. ssh-add -l liste les clés chargées dans l'agent.

Pourquoi git pull échoue-t-il seulement avec sudo ?

sudo s'exécute en root, donc SSH lit /root/.ssh et n'atteint en général pas votre agent. Lancez Git avec votre utilisateur et corrigez plutôt le propriétaire du dossier.

Sources

Autres guides : Messages d'erreur

Tous les guides