Skip to content

/commands/ssh-protocol/remove-host-from-known-hosts

ssh-keygen -R hostname: remove a host key from known_hosts

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash)updated
tool
SSH protocol
versions
OpenSSH 7.x – 10.x
os
linux, macos, windows

ssh-keygen -R hostname deletes every key stored for hostname in ~/.ssh/known_hosts and keeps the previous file as known_hosts.old. Run it after a server was reinstalled or its host key was rotated, when ssh refuses to connect with REMOTE HOST IDENTIFICATION HAS CHANGED. The next ssh hostname asks you to accept the new key.

Remove, find and hash entries

The block builds a small known_hosts with three entries for the same key, removes two of them, and then hashes the rest. -f points at a file other than the default ~/.ssh/known_hosts:

bash
ssh-keygen -q -t ed25519 -N '' -f hostkey
key=$(cut -d' ' -f1,2 hostkey.pub)
printf 'server.example.com %s\n[server.example.com]:2222 %s\n192.0.2.10 %s\n' "$key" "$key" "$key" > known_hosts
echo "--- find"
ssh-keygen -F server.example.com -f known_hosts | cut -c1-48
echo "--- remove"
ssh-keygen -R server.example.com -f known_hosts
ssh-keygen -R '[server.example.com]:2222' -f known_hosts
ssh-keygen -R not-there.example -f known_hosts; echo "exit $?"
echo "--- left"
cut -d' ' -f1,2 known_hosts | cut -c1-30
echo "--- hash"
ssh-keygen -H -f known_hosts 2>&1
cut -c1-3 known_hosts
ssh-keygen -F 192.0.2.10 -f known_hosts | head -1

Output

--- find
# Host server.example.com found: line 1
server.example.com ssh-ed25519 AAAAC3NzaC1lZDI1N
--- remove
# Host server.example.com found: line 1
known_hosts updated.
Original contents retained as known_hosts.old
# Host [server.example.com]:2222 found: line 1
known_hosts updated.
Original contents retained as known_hosts.old
Host not-there.example not found in known_hosts
exit 0
--- left
192.0.2.10 ssh-ed25519
--- hash
WARNING: known_hosts.old contains unhashed entries
Delete this file to ensure privacy of hostnames
known_hosts updated.
Original contents retained as known_hosts.old
|1|
# Host 192.0.2.10 found: line 1

The [server.example.com]:2222 entry is separate from the plain one: OpenSSH stores keys for non-default ports under [host]:port, so -R server.example.com does not touch it.

Options

CommandWhat it does
ssh-keygen -R HOSTRemove all keys for HOST from ~/.ssh/known_hosts; the old file becomes known_hosts.old.
ssh-keygen -R '[HOST]:PORT'Remove the entry for a server on a non-standard port.
ssh-keygen -R 192.0.2.10Remove the entry stored under the IP address (ssh may record both name and IP).
ssh-keygen -F HOSTPrint the matching lines and their line numbers, also for hashed entries.
ssh-keygen -HHash every host name in the file so it does not reveal which servers you use.
ssh-keygen -f FILE ...Work on FILE instead of ~/.ssh/known_hosts.
ssh-keyscan HOSTFetch the current host key of a server, to compare its fingerprint before trusting it.

Pitfalls

  • ssh may have stored the key under the IP address as well as the name. If the warning persists, run -R for the IP too; the warning message names the offending line.
  • Hashed entries (|1|...) cannot be searched with grep; use ssh-keygen -F. After -H, ssh-keygen warns that known_hosts.old still contains the names in clear text: delete it once the new file works.
  • System-wide keys in /etc/ssh/ssh_known_hosts are not changed by -R on your user file. Edit that file as root or pass it with -f.
  • On Windows the file is %USERPROFILE%\.ssh\known_hosts; the command is the same in PowerShell with the OpenSSH client.

After removing the key, connect once and compare the fingerprint ssh shows with the one the server administrator publishes (ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub on the server). The fingerprint page shows how to read both formats. For the full warning and its causes, see remote host identification has changed.

FAQ

Is it safe to remove the old key when ssh warns that the host identification has changed?

Only after you have confirmed that the server really got a new key, for example because it was reinstalled, and you have compared the new fingerprint with one obtained over a trusted channel. Otherwise the warning may be a man-in-the-middle attack.

Why does ssh-keygen -R not remove the entry for a server on port 2222?

Entries for non-standard ports are stored as [host]:port. Pass the same form, quoted so the shell leaves the brackets alone: ssh-keygen -R '[host]:2222'.

Can I just delete the line with a text editor?

Yes, the warning prints the offending file and line number. ssh-keygen -R is safer because it also finds hashed entries, which you cannot recognise by eye, and it keeps a backup in known_hosts.old.

Sources