The remote asked for SSH auth and your key didn't work: not loaded, wrong key on the account, or sshd config quirks. Test the exact path with one debug command.
ssh -T git@github.com shows exactly what the server thinks of your keys. If none are offered (agent empty, wrong path in ~/.ssh/config), auth can't happen.
config points github.com at an old key file, or permissions on the key (must be 600) make ssh refuse to use it silently.
CI, cron, and sudo run with another HOME: your ~/.ssh never gets read. Use an explicit key path or deploy keys with absolute paths.
ssh -T git@github.com # 'Hi <user>! You've successfully authenticated' or the failure reason
ssh-add -l ; ls -la ~/.ssh/ ; grep -A3 -i github ~/.ssh/config 2>/dev/null
chmod 700 ~/.ssh && chmod 600 ~/.ssh/id_ed25519 && chmod 644 ~/.ssh/id_ed25519.pub
cat ~/.ssh/id_ed25519.pub # paste into GitHub → Settings → SSH keys (or repo → Deploy keys for single-repo access)
Deploy keys are repo-scoped: prefer them for servers/CI over adding a personal key everywhere. https:// clone with a PAT or credential helper is the pragmatic fallback when SSH is blocked by the network (port 22 filtering).
CI runs with a different HOME and no ssh-agent. Put the key at an absolute path and reference it explicitly: GIT_SSH_COMMAND='ssh -i /etc/ci/id_ed25519 -o IdentitiesOnly=yes' git fetch...
Yes — switch the remote (git remote set-url origin https://github.com/user/repo.git) and use a PAT/credential helper. Slightly less convenient than SSH keys but firewall-friendly.
Our most-documented failures, packaged as ready-to-ship starter kits: Docker, Kubernetes, and Terraform.
Browse the template store →One-time. Yours to modify. Instant download from the NinjaOps template store.