SSH refuses to connect and prints one of two things. They look similar and mean different things, so read yours before you change anything. ```text Host key verification failed. ``` The line above it is the one that matters. This guide covers both forms, tested with OpenSSH 10.3. ## Which Message Did You Get? ### The host is unknown ```text No ED25519 host key is known for github.com and you have requested strict checking. Host key verification failed. ``` You've never connected to this host, and `StrictHostKeyChecking=yes` refuses to accept a key it hasn't seen. Routine. Go to "Add a host key you trust". ### The host key changed ```text @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that a host key has just been changed. The fingerprint for the ED25519 key sent by the remote host is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU. Offending ED25519 key in /Users/you/.ssh/known_hosts:1 Host key for github.com has changed and you have requested strict checking. Host key verification failed. ``` The host answered with a key that doesn't match the one you recorded. Usually the server was rebuilt or the provider rotated keys. Occasionally it means what the warning says. Don't delete the line until you've checked which. ## Step 1: Decide Whether the Change Is Legitimate The warning prints the fingerprint the host just sent. Compare it against a source that isn't the connection you're doubting: * **GitHub, GitLab, Bitbucket:** each publishes its fingerprints. GitHub's are on its [SSH key fingerprints][github-fingerprints] page. * **A machine you run:** read the fingerprint on the console, out of band: ```bash # on the server itself ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub ``` * **A cloud instance:** the provider prints host keys in the serial console log at first boot. Matching fingerprint means the key changed for a benign reason. No match, or no way to check, means stop and ask whoever runs the host. Everything below assumes you verified it. ## Step 2: Remove the Old Key The error names the file and the line, for example `Offending ED25519 key in /Users/you/.ssh/known_hosts:1`. Remove that host's entry: ```bash ssh-keygen -R github.com ``` That rewrites `known_hosts`, keeping a backup at `known_hosts.old`. It beats editing by hand, which is how people delete the wrong line. For a host on a non-standard port, quote the bracketed form: ```bash ssh-keygen -R "[example.com]:2222" ``` ## Step 3: Add the Key You Verified Fetch the key and check its fingerprint before trusting it: ```bash ssh-keyscan -t ed25519 github.com > /tmp/newkey ssh-keygen -lf /tmp/newkey ``` Compare the printed fingerprint with the published one. When it matches, append it: ```bash cat /tmp/newkey >> ~/.ssh/known_hosts ``` Or simply connect and accept the prompt, now that you know which fingerprint to expect: ```bash ssh -T git@github.com ``` `ssh-keyscan` piped straight into `known_hosts` is common advice and skips the check entirely: it trusts whatever answers. Print the fingerprint first. ## Step 4: Check Permissions if the Error Persists SSH ignores `known_hosts` when the file or directory is too permissive, which produces the same failure in a loop: ```bash chmod 700 ~/.ssh chmod 600 ~/.ssh/known_hosts ls -l ~/.ssh/known_hosts ``` On a shared machine, a system-wide file can also carry a stale entry: ```bash sudo ssh-keygen -f /etc/ssh/ssh_known_hosts -R github.com ``` ## What Not to Do ```text StrictHostKeyChecking no ``` Turning off checking makes the message disappear and gives up the thing SSH is doing for you: noticing that the machine answering today is not the machine you trusted yesterday. The same goes for `-o StrictHostKeyChecking=no` pasted into a script. If an automated job needs to connect without a prompt, pin the key instead of skipping the check: ```bash ssh-keyscan -t ed25519 github.com >> ~/.ssh/known_hosts # once, fingerprint verified ssh -o StrictHostKeyChecking=yes -T git@github.com # then require the match ``` Ephemeral CI runners are the one place `accept-new` is reasonable: it accepts an unknown host once, but still fails when a known key changes. ```bash ssh -o StrictHostKeyChecking=accept-new -T git@github.com ``` ## Verify ```bash ssh -T git@github.com # Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access. git pull ``` ## Related Content * [Fix Permission Denied (publickey) in SSH and GitHub][ssh-publickey] covers the error you hit after the host is trusted but your key isn't accepted. * [Fix: src refspec main does not match any][refspec] covers the push error that has nothing to do with SSH. ## References * [GitHub's SSH key fingerprints][github-fingerprints], the out-of-band source to compare against. * [ssh-keygen(1)][ssh-keygen-man], for `-R` and `-lf`. * [sshd(8) known_hosts format][known-hosts-man], for entry syntax, including bracketed ports. [ssh-publickey]: https://jeffbailey.us/blog/2019/11/10/setting-ssh-key-permissions/ [refspec]: https://jeffbailey.us/blog/2026/09/20/git-src-refspec-does-not-match-any/ [github-fingerprints]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints [ssh-keygen-man]: https://man.openbsd.org/ssh-keygen [known-hosts-man]: https://man.openbsd.org/sshd#SSH_KNOWN_HOSTS_FILE_FORMAT