SSH host key verification failed: the safe fix (not the insecure one)
⏱️ 2 min read
Why SSH is being stubborn
SSH pins every server's identity in ~/.ssh/known_hosts. When the key does not match, the connection dies with a scary warning. That warning is the entire security model of SSH: without it, a DNS hijack or MITM could hand you a lookalike server.
First: did the server legitimately change?
Rebuilt the box, new IP, or provider re-provisioned the VM? Then the new key is correct and pinning it is safe:
ssh-keygen -R hostname ssh user@hostname # accept the new fingerprint after checking it
Verify the fingerprint out of band when stakes are high: your provider's console shows the host key, or run ssh-keyscan hostname and compare against what the provider published.
If you manage many servers
Pinning keys manually per box does not scale, and disabling checks globally definitely does not. The middle ground: pre-populate known_hosts in provisioning (cloud-init, Ansible known_hosts module, or a config-managed file), so every new box is pinned before a human ever types ssh. Teams doing this per-device instead of per-person should look at posture-aware access: NordLayer handles device checks before the tunnel opens. (Partner link.)
Why not just disable checking?
StrictHostKeyChecking=no accepts ANY key the first time, which converts silent MITM attacks into full credential compromise. It survives in copy-pasted Stack Overflow snippets and should not survive in your runbooks. Accept new keys explicitly, automate the pinning, keep the guardrail.