Deploy Error Decoder

'Host key verification failed' — fix SSH known_hosts safely

Quick answer: Host key verification failed means SSH won't connect because it can't verify the server's host key against known_hosts. It's usually a first-time connection, a server that was rebuilt, or an empty known_hosts in CI. Add the key safely with ssh-keyscan host >> ~/.ssh/known_hosts; if it warns "REMOTE HOST IDENTIFICATION HAS CHANGED," verify the fingerprint before removing the old entry.

What the error looks like

SSH refuses the connection, so git or your deploy can't proceed:

Host key verification failed.
fatal: Could not read from remote repository.

# the louder, scarier variant:
@@@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!

This check is a security feature, not a nuisance: SSH is protecting you from connecting to an impersonated host. Most of the time it's benign — but the "changed" warning deserves a real look before you override it.

Why it happens

First connection to the host

The key isn't in known_hosts yet, so SSH can't verify it (common in non-interactive contexts).

The server was rebuilt

A reprovisioned host has a new key that no longer matches the saved entry.

Empty known_hosts in CI

A fresh CI runner has no known_hosts, so every host is "unknown".

A genuine key change

Rarely, the key changed because something is intercepting the connection — the case the check exists for.

Resolve it safely in three steps

1

See what SSH has on file

ssh-keygen -F github.com        # is there a known_hosts entry?
2

Verify the fingerprint, then add it

ssh-keyscan github.com 2>/dev/null | ssh-keygen -lf -
# compare to the host's PUBLISHED fingerprint, then:
ssh-keyscan github.com >> ~/.ssh/known_hosts
3

Only after verifying, remove a stale entry

ssh-keygen -R old-host.example.com   # drops the outdated key
# then re-add via ssh-keyscan as above
The real fix

Pin known hosts; verify before you trust

The safe pattern, especially in CI, is to pin a verified known_hosts rather than disabling the check. Never set StrictHostKeyChecking no for real hosts — it throws away the exact protection that catches a man-in-the-middle. Add the key after confirming the fingerprint against the provider's published value.

How Infraveil handles this

Trust by inspection, not assertion

Verifying a key fingerprint before you trust it is the same principle Infraveil is built on. The agent on your own servers verifies signatures on what it runs — including Infraveil's own — so trust comes from inspection, not a vendor's say-so. Every action is recorded in a tamper-evident trail you can check.

Signatures are verified before code runs — trust by inspection
The agent verifies even Infraveil's own signed instructions
Every action recorded in a trail you can inspect, on servers you control

Frequently asked questions

What does 'Host key verification failed' mean?

SSH couldn't match the server's host key to an entry in known_hosts, so it refused to connect. It's a first connection, a rebuilt server, or (rarely) a real warning that the key changed.

How do I fix it in CI?

Pin a verified host key into the runner's known_hosts, e.g. ssh-keyscan github.com >> ~/.ssh/known_hosts after checking the fingerprint against the provider's published value.

What does 'REMOTE HOST IDENTIFICATION HAS CHANGED' mean?

The host's key differs from what you saved. Usually the server was rebuilt — but verify the new fingerprint before removing the old entry, since this warning also catches interception.

Should I disable StrictHostKeyChecking?

No, not for real hosts. It removes the protection against connecting to an impersonated server. Add and verify the host key instead.