WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! / Host key verification failed.
Last updated: March 2026
When you see this error, SSH is telling you that the server's cryptographic identity does not match what it recorded during your last connection. This is a security feature, not a bug. Whether it is a routine infrastructure change or a genuine alarm depends on context — this guide explains what to check, the safe fix, and when to be worried.
The Full Error Message
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ 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 was just changed.
The fingerprint for the ED25519 key sent by the remote host is
SHA256:AbCdEfGhIjKlMnOpQrStUvWxYz1234567890abc.
Please contact your system administrator.
Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
Offending ED25519 key in /home/user/.ssh/known_hosts:7
Host key for hostname has changed and you have requested strict checking.
Host key verification failed.
SSH refuses to connect entirely. This is by design.
What known_hosts Is
When you first connect to a server, SSH records the server's public host key in ~/.ssh/known_hosts. On every subsequent connection, SSH compares the server's key to this record. If they match, the connection proceeds. If they do not match, you see this error.
The known_hosts file looks like this:
hostname,203.0.113.10 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAbc...
192.168.1.100 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIXyz...
Each line contains the hostname (and/or IP), the key type, and the base64-encoded public key.
Why the Error Appears
Legitimate reasons (safe to resolve)
- Server was rebuilt or reinstalled. A fresh OS installation generates new host keys. This is the most common cause.
- IP address reassigned. A new server was given the same IP or hostname as an old one. Common in cloud environments, VPSes, and DHCP networks.
- Server's host keys were regenerated. An administrator ran
ssh-keygen -Aor equivalent to regenerate host keys. - You are connecting through a load balancer or bastion host that routes to a different backend server than before.
- You changed from connecting by IP to connecting by hostname (or vice versa), and SSH has both records.
Concerning reasons (do not ignore)
- Man-in-the-middle (MITM) attack. An attacker has positioned themselves between you and the server and is presenting their own key to intercept the session.
- DNS hijacking. The hostname resolves to a different IP than expected.
- ARP spoofing on a local network.
Verifying the Situation Before Fixing
Before removing the old key, confirm the server's actual fingerprint through an out-of-band channel:
# On the server (via console, cloud dashboard, or physical access):
ssh-keygen -l -f /etc/ssh/ssh_host_ed25519_key.pub
# or
for f in /etc/ssh/ssh_host_*_key.pub; do ssh-keygen -l -f "$f"; done
Compare this fingerprint with what SSH reported in the error:
The fingerprint for the ED25519 key sent by the remote host is
SHA256:AbCdEfGhIjKlMnOpQrStUvWxYz1234567890abc.
If the fingerprints match, the server key genuinely changed for a legitimate reason. Proceed with the fix below.
If you cannot verify through an out-of-band channel and you did not expect a change, treat it as suspicious until confirmed.
The Safe Fix: ssh-keygen -R
Remove the old (stale) host key entry from known_hosts:
ssh-keygen -R hostname
Replace hostname with the exact hostname or IP you use to connect. Examples:
ssh-keygen -R 203.0.113.10
ssh-keygen -R myserver.example.com
ssh-keygen -R "[myserver.example.com]:2222" # Non-standard port
SSH creates a backup of known_hosts and removes the offending entry:
# Host hostname found: line 7
/home/user/.ssh/known_hosts updated.
Original contents retained as /home/user/.ssh/known_hosts.old
Now connect again:
ssh user@hostname
SSH will show the new fingerprint and ask you to confirm:
The authenticity of host 'hostname (203.0.113.10)' can't be established.
ED25519 key fingerprint is SHA256:AbCdEfGhIjKlMnOpQrStUvWxYz1234567890abc.
Are you sure you want to continue connecting (yes/no/[fingerprint])?
Type yes (or paste the expected fingerprint to verify it). The new key is added to known_hosts and future connections will proceed without prompting.
Manual known_hosts Edit
If you prefer to edit the file directly:
# The error message tells you the line number
# "Offending ED25519 key in /home/user/.ssh/known_hosts:7"
# Delete line 7:
sed -i '7d' ~/.ssh/known_hosts
# Or open in an editor
nano ~/.ssh/known_hosts
# Find the line with the hostname and delete it
You can also search for the specific host:
grep -n "hostname" ~/.ssh/known_hosts
# Find the line number, then delete it
sed -i '/hostname/d' ~/.ssh/known_hosts
Be careful with sed -i if the hostname string could match multiple entries (e.g., server could match server, server2, myserver).
StrictHostKeyChecking Options
The StrictHostKeyChecking directive in ~/.ssh/config controls SSH's behavior when a host key is unknown or changed.
| Value | Behavior |
|---|---|
yes |
Refuse connections to unknown hosts; fail on changed keys. Most secure. Default behavior when known_hosts exists. |
accept-new |
Automatically add new (unknown) host keys to known_hosts; still fail if a key has changed. Good balance for most use. |
no |
Accept all host keys without checking. Insecure — never use on untrusted networks. |
ask (default) |
Prompt for new hosts; fail on changed keys. |
Configuring per-host in ~/.ssh/config
# Automatically trust new hosts (but still check changed keys)
Host internal-servers
HostName 10.0.0.*
StrictHostKeyChecking accept-new
# Specific host where keys change often (e.g., ephemeral cloud instances)
Host staging-ephemeral
HostName staging.example.com
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
UserKnownHostsFile /dev/null discards the known_hosts entry entirely after each session. Useful for ephemeral servers in CI/CD pipelines where keys change on every provision.
See the SSH Config File guide for full details on config file options.
Command-line one-time override
For a single connection only:
ssh -o StrictHostKeyChecking=no user@hostname
ssh -o "StrictHostKeyChecking=accept-new" user@hostname
When to Be Genuinely Worried
Take the warning seriously if:
- You did not rebuild the server, reassign the IP, or make any infrastructure change.
- You are connecting from a public or untrusted network (coffee shop, airport, hotel WiFi).
- The fingerprint shown does not match what you can verify from the server console.
- DNS shows a different IP than expected:
nslookup hostnamereturns something unexpected. - Colleagues connecting from different networks do not see the error (suggesting your specific network path is compromised, not the server).
If you suspect a MITM attack:
1. Do not type any credentials or commands.
2. Press Ctrl+C to abort the connection.
3. Verify the server's IP and fingerprints through the cloud dashboard or a trusted out-of-band channel.
4. Check DNS resolution from multiple sources (e.g., dig @8.8.8.8 hostname).
FAQ
Q: I get this error every time I connect to a Vagrant or Docker container. How do I stop it?
Vagrant and Docker containers generate new host keys on each provisioning. For local development only, use:
# In your SSH config for local vagrant/docker hosts
Host 127.0.0.1
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
Never use this for production hosts.
Q: I see "Offending key in /home/user/.ssh/known_hosts:7". What does the number mean?
It is the line number in known_hosts where the old (now mismatched) key is stored. You can delete that specific line with sed -i '7d' ~/.ssh/known_hosts or use ssh-keygen -R hostname to remove it automatically.
Q: Can I prevent this error when deploying to many short-lived cloud instances?
Yes. In your automation scripts or ~/.ssh/config, set:
Host *
StrictHostKeyChecking accept-new
This trusts new keys but still protects against changed keys for previously seen hosts. For fully ephemeral infrastructure, combine with UserKnownHostsFile /dev/null.