You try to SSH into a server and see this warning:

bash
$ ssh user@server.example.com
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    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.
Fingerprint for the RSA key sent by the remote host is
SHA256:abc123...
Please contact your system administrator.
Add correct host key in /home/user/.ssh/known_hosts to get rid of this message.
Offending RSA key in /home/user/.ssh/known_hosts:5
RSA host key for server.example.com has changed and you have requested strict checking.
Host key verification failed.

This error occurs when the server's host key doesn't match what's stored in your known_hosts file. This could indicate a security issue (someone impersonating the server) or, more commonly, the server was reinstalled or its SSH keys were regenerated.

Understand the Security Implications

Before proceeding, consider why the key changed:

  • Server reinstalled - New OS installation generates new keys
  • Cloud instance recreated - Same IP but new instance
  • SSH package reinstalled - Keys regenerated
  • Man-in-the-middle attack - Someone intercepting your connection

If you're not expecting a key change, verify the server's identity through another channel before proceeding.

Quick Fix: Remove Old Key

The error message tells you the line number in known_hosts:

bash
Offending RSA key in /home/user/.ssh/known_hosts:5

Remove that specific line:

bash
sed -i '5d' ~/.ssh/known_hosts

Or use the ssh-keygen command to remove by hostname:

bash
ssh-keygen -R server.example.com

This removes all keys for that hostname. Now reconnect:

bash
ssh user@server.example.com

You'll see the new key prompt:

bash
The authenticity of host 'server.example.com (192.168.1.100)' can't be established.
ECDSA key fingerprint is SHA256:xyz789...
Are you sure you want to continue connecting (yes/no/[fingerprint])?

Type yes to accept the new key.

Remove Key by IP Address

If the hostname resolves to multiple IPs or you connect by IP:

bash
ssh-keygen -R 192.168.1.100

Remove both hostname and IP:

bash
ssh-keygen -R server.example.com
ssh-keygen -R 192.168.1.100

Verify the New Key Fingerprint

Don't blindly accept the new key. Verify it matches the server. On the server:

bash
ssh-keygen -l -f /etc/ssh/ssh_host_ecdsa_key.pub

Or for RSA:

bash
ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub

Compare this fingerprint with what SSH shows you. They should match exactly.

For additional security, use the fingerprint verification option:

bash
ssh -o "VerifyHostKeyDNS=yes" user@server.example.com

Hash Known Hosts (Optional)

To prevent someone from reading hostnames in your known_hosts file, enable hashing:

bash
ssh-keygen -H

This hashes all hostnames in your existing known_hosts file. New entries use hashing if you add to your ~/.ssh/config:

bash
HashKnownHosts yes

Handle Multiple Keys for Same Host

If you have multiple servers behind a load balancer with the same hostname:

bash
ssh user@loadbalancer.example.com

You might get this error because each backend server has different keys. Use the StrictHostKeyChecking option:

bash
ssh -o StrictHostKeyChecking=no user@loadbalancer.example.com

Better yet, configure this in ~/.ssh/config:

bash
Host loadbalancer.example.com
    StrictHostKeyChecking no
    UserKnownHostsFile /dev/null

Note: This reduces security. Only use in controlled environments where you understand the risk.

Bulk Remove Keys

If a server's IP changed or you have many stale entries:

bash
ssh-keygen -R "# Comment with old info"

To clear all known hosts (use with caution):

bash
rm ~/.ssh/known_hosts ~/.ssh/known_hosts.old

Check for Duplicate Entries

Sometimes the same host appears multiple times with different keys:

bash
grep server.example.com ~/.ssh/known_hosts

Remove all instances:

bash
ssh-keygen -R server.example.com

Accept Key Automatically for Scripts

For automated scripts that can't handle interactive prompts:

bash
ssh -o StrictHostKeyChecking=accept-new user@server.example.com

The accept-new option automatically accepts new keys but rejects changed keys, providing some security.

Alternative: Use Known Hosts File Per Host

Maintain separate known hosts files for different environments:

bash
ssh -o UserKnownHostsFile=~/.ssh/known_hosts_production user@prod.example.com
ssh -o UserKnownHostsFile=~/.ssh/known_hosts_staging user@staging.example.com

In ~/.ssh/config:

``` Host prod.example.com UserKnownHostsFile ~/.ssh/known_hosts_production

Host staging.example.com UserKnownHostsFile ~/.ssh/known_hosts_staging ```

Prevent Future Issues

When rebuilding servers, preserve SSH host keys:

```bash # Backup before rebuild tar czf ssh_host_keys.tar.gz /etc/ssh/ssh_host_*

# After rebuild, restore tar xzf ssh_host_keys.tar.gz -C / systemctl restart sshd ```

Or generate keys with a specific seed for reproducibility.

Resolution Checklist

  1. 1.Identify the line number in the error message
  2. 2.Remove the old key: ssh-keygen -R hostname
  3. 3.Verify the new key fingerprint with the server
  4. 4.Accept the new key by typing yes
  5. 5.Consider hashing known hosts for privacy

The host key verification error is a security feature protecting you from MITM attacks. Always verify key changes through another channel when possible, but in most cases it's simply a reinstalled server with new keys.