Fix "WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!" in SSH

Quick fix

First confirm the server really was reinstalled or replaced (check the fingerprint on its console). Then delete only the stale entry and reconnect, accepting the new key.

ssh-keygen -R server.example.com
# also remove the IP entry if you connect by IP
ssh-keygen -R 203.0.113.10
ssh [email protected]

The full warning looks like this:

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    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:9mQx2...
Please contact your system administrator.
Add correct host key in /home/alice/.ssh/known_hosts to get rid of this message.
Offending ED25519 key in /home/alice/.ssh/known_hosts:14
Host key for server.example.com has changed and you have requested strict checking.
Host key verification failed.

What the error means

Every SSH server has a host key pair. The first time you connect, your client stores the server's public host key in ~/.ssh/known_hosts. On every later connection it checks that the server presents the same key. When the key differs, SSH refuses to continue because it cannot tell a legitimately rebuilt server from an attacker sitting between you and the real one.

The message tells you three useful things: the new fingerprint (SHA256:...), the key type, and the file and line of the old entry (known_hosts:14).

Step 1: verify the new fingerprint

Do this before removing anything. Get the real fingerprint through a channel that does not use this SSH connection: the server's console, your cloud provider's web console or serial log, or the administrator.

# on the server itself
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

Example output:

256 SHA256:9mQx2... root@server (ED25519)

Match the key type shown in the warning (ED25519, ECDSA or RSA) and compare the SHA256: string. If it matches, the change is legitimate. If it does not match, or nobody can explain why the key changed, do not connect: treat it as a possible interception and investigate the network path.

Cloud servers

Most cloud providers print the host key fingerprints to the instance's console or boot log on first boot. That log is a trustworthy source for comparison.

Step 2: remove only the stale entry

ssh-keygen -R deletes all keys for a host from known_hosts and keeps a backup at known_hosts.old. It works even when host names are hashed (HashKnownHosts yes, the default on Debian and Ubuntu), where you cannot find the line by eye.

ssh-keygen -R server.example.com
ssh-keygen -R 203.0.113.10
# servers on a non-standard port are stored with brackets
ssh-keygen -R '[server.example.com]:2222'

Alternatively, delete the exact line number from the warning:

sed -i '14d' ~/.ssh/known_hosts

Then connect again. SSH shows the new fingerprint and asks Are you sure you want to continue connecting (yes/no/[fingerprint])?. You can paste the fingerprint you verified in step 1 at that prompt and SSH compares it for you.

If the warning came from sudo ssh, sudo git or a service, the entry is in /root/.ssh/known_hosts or that service user's home, so run ssh-keygen -R as that user. System-wide entries live in /etc/ssh/ssh_known_hosts.

Common causes (most likely first)

The server was reinstalled or rebuilt

A fresh OS install generates new host keys. Same for rebuilding a VM from an image, restoring a snapshot that predates a key rotation, or reinstalling openssh-server after deleting /etc/ssh/ssh_host_*. Verify and remove the old entry as above. To avoid this when rebuilding a server you control, back up /etc/ssh/ssh_host_* and restore those files on the new install.

The IP or name now points to a different machine

Cloud providers reuse public IPs, home routers hand out the same DHCP address to a new device, and DNS records get moved. The key is "changed" because it is a different computer. Check that you are connecting to the machine you think you are before accepting.

Several machines behind one name

A load balancer, round-robin DNS or a failover pair can send you to different servers with different host keys. The real fix is for the admin to give all nodes the same host keys or to publish them all; as a user, add each node's verified key rather than switching off checking.

Host keys were rotated on purpose

Administrators sometimes regenerate keys, for example to drop old RSA keys. OpenSSH supports announcing new keys in advance (UpdateHostKeys, on by default in current clients), so you may only see the warning if you skipped that period.

An actual man-in-the-middle

Rare, but possible on hostile Wi-Fi, a compromised router or a corporate SSL/SSH inspection proxy. A fingerprint that does not match the server console is the tell. Disconnect and use another network.

What not to do

Do not disable host key checking globally

Answers that suggest StrictHostKeyChecking no plus UserKnownHostsFile /dev/null in ~/.ssh/config for Host * remove SSH's only defence against interception for every server you ever connect to. Fix the one entry instead.

Deleting the whole known_hosts file also "works", but forgets every key you previously trusted, so the next real attack would go unnoticed.

For short-lived test VMs on your own isolated lab network, a narrowly scoped block is a reasonable compromise, because those keys change on every rebuild:

# ~/.ssh/config: only for a private lab subnet you control
Host 192.168.122.*
    StrictHostKeyChecking accept-new
    UserKnownHostsFile ~/.ssh/known_hosts_lab

accept-new automatically trusts unknown hosts but still refuses changed keys, which is much safer than no; clear the separate lab file when you rebuild VMs.

Distro notes

  • Ubuntu, Debian, Mint: hostnames in known_hosts are hashed by default, so use ssh-keygen -R or the line number rather than searching for the name.
  • Fedora, Arch, openSUSE: entries are stored in clear text unless you enable HashKnownHosts, but ssh-keygen -R works the same way.
  • On all distros the server's own keys are in /etc/ssh/ssh_host_*_key.pub.

How to prevent it

  • Back up and restore /etc/ssh/ssh_host_* when you reinstall a server you want to keep the same identity.
  • For automation, distribute verified host keys (configuration management, or SSHFP DNS records with DNSSEC) instead of turning off checking. ssh-keyscan alone is trust-on-first-use, so verify its output.
  • Give each server a stable name in ~/.ssh/config so IP reuse does not hit you unexpectedly.

After reconnecting, if you get Permission denied (publickey), the rebuilt server also lacks your authorized key; see the SSH keys guide. More client options are in the SSH cheat sheet.

Frequently asked questions

How do I remove a host from known_hosts?

Run ssh-keygen -R hostname, and repeat with the IP address if you also connect by IP. For a non-standard port use ssh-keygen -R '[hostname]:2222'.

Is it safe to just delete known_hosts?

It works but throws away every host key you have verified, so you lose protection for all servers. Remove only the one offending entry with ssh-keygen -R.

Why did the host key change?

Usually because the server was reinstalled, its SSH host keys were regenerated, or the IP address now belongs to a different machine. Rarely, it is an actual interception attempt, which is why you should verify the new fingerprint.

Should I set StrictHostKeyChecking no?

Not globally. It removes the only protection SSH has against man-in-the-middle attacks. Fix the one stale entry instead.

Spotted a mistake or a command that no longer works? Send a correction — pages are re-checked when reports come in.