SSH refused to connect with a block of @ symbols and WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!. The server is presenting a different host key than the one SSH remembered. If you know why it changed, the fix is one command. If you do not, stop and find out first, because this is exactly what a machine-in-the-middle attack looks like.
When it is benign
The host key legitimately changes when:
- The server was rebuilt, reinstalled, or reprovisioned.
- A new VM got the same IP address as an old one (very common with cloud and DHCP).
- You are connecting through a load balancer or a port-forward to a different backend.
When it is not
If nothing changed on the server and you did not expect a new key, treat it as a real warning. Do not blindly delete the entry. Verify the new fingerprint out of band (from the provider console, the server's /etc/ssh/ssh_host_ed25519_key.pub, or a colleague) before trusting it.
The fix: remove the stale entry
Once you are sure the new key is legitimate, drop the old line from known_hosts:
ssh-keygen -R server.example.comThat removes every key stored for that host. The next connection shows the normal "authenticity of host ... can't be established, continue?" prompt; type yes and the new key is saved. For a host on a non-standard port, include it: ssh-keygen -R '[server.example.com]:2222'.
You can also open ~/.ssh/known_hosts and delete the offending line by hand. The warning text tells you the exact line number (Offending key in /home/you/.ssh/known_hosts:14).
If the warning persists after that, you probably have a second entry keyed by the IP address (or a hostname,ip line). Clear both forms:
ssh-keygen -R server.example.com
ssh-keygen -R 203.0.113.10It also happens on git clone, pull, and push
The same wall appears when Git talks to GitHub or GitLab over SSH, because the transport underneath is SSH. A git pull that fails with Host key verification failed is the identical problem, and the identical fix: ssh-keygen -R github.com, then let the next connection re-trust the host. For GitHub specifically, do not blindly accept the new key, verify it against GitHub's published SSH key fingerprints page first, since a changed GitHub host key is far more likely an interception than a rebuild.
Verify the new fingerprint before you trust it
To compare against what the provider shows you, print the fingerprint the server is presenting:
ssh-keygen -lf <(ssh-keyscan server.example.com 2>/dev/null)If it matches the console value, accept it. If it does not, you have a real problem, not a stale entry.
A safer default for ephemeral hosts
If you spin up and tear down servers constantly (CI, test VMs) on reused IPs, the warning is noise. Rather than disabling host checking entirely (StrictHostKeyChecking no, which removes the protection), use accept-new, which trusts new hosts but still fails if a known key changes:
# ~/.ssh/config
Host *.test.example.com
StrictHostKeyChecking accept-new
FAQ
See also
- How to Create an SSH Key in 2026: your client key, separate from the server's host key this article is about.
- Fix SSH "Permission denied (publickey)": the other SSH wall you hit, on the auth side.
- SSH Cheat Sheet: known_hosts, host keys, and config directives.
Sources
Authoritative references this article was fact-checked against.
- ssh(1) manual page (OpenBSD)man.openbsd.org
- ssh-keygen(1) manual page (OpenBSD)man.openbsd.org





