{"id":"2ab2c4f1-e118-425c-810a-ca5cb7bab347","task":"Resolve ssh's \"REMOTE HOST IDENTIFICATION HAS CHANGED\" / host-key verification failure by safely updating known_hosts, distinguishing a legitimate host-key rotation from a possible man-in-the-middle attack.","domain":"openssh.com","steps":["Read the full warning: ssh names the key type and the exact known_hosts file/line it conflicts with, e.g. \"Offending ED25519 key in /home/you/.ssh/known_hosts:23\". Note the hostname, key type, and line number before changing anything.","Verify the new key out-of-band before trusting it -- do not just delete the old entry to silence the warning. Options: ask the server administrator for the current fingerprint; or, if the domain publishes SSHFP records, run `ssh-keygen -r <host>` to see the expected record format and `dig -t SSHFP <host>` to query DNS, then connect with `ssh -o \"VerifyHostKeyDNS ask\" <user>@<host>` so ssh reports whether the presented key matches DNS.","Once you've confirmed the change is legitimate (planned host rebuild, key rotation, cloud IP reuse, etc.), remove the stale entry: ssh-keygen -R <hostname> (use [host]:port if non-default, and -f <known_hosts_file> if it's not the default ~/.ssh/known_hosts). This deletes every key recorded for that hostname; copy known_hosts first if you want a safety net.","Reconnect normally: ssh <user>@<host>. With the default StrictHostKeyChecking=ask you'll see the new key's fingerprint and must type \"yes\" to add it to known_hosts before the connection proceeds.","For pre-provisioning many hosts at once (e.g. a fresh fleet) rather than accepting interactively, you can seed known_hosts directly: ssh-keyscan -t ed25519 <host> >> ~/.ssh/known_hosts, or ssh-keyscan -H <host> >> ~/.ssh/known_hosts to store hashed hostnames. Only do this over a network path you already trust -- see gotchas."],"gotchas":["ssh-keyscan explicitly cannot verify what it fetches: an attacker on the network with the ability to intercept traffic could substitute their own host keys -- its output must be verified out of band, or only trusted directly if the network path is already trusted. Docs: https://man.openbsd.org/ssh-keyscan.1","Never respond to a changed-host-key warning by setting StrictHostKeyChecking=no/off or piping \"yes\" automatically in a script on an untrusted network: per ssh_config(5), \"no\"/\"off\" makes ssh automatically add new host keys and allow connections to hosts with changed hostkeys to proceed -- this removes the exact MITM protection the warning exists to give you. Reserve that setting for fully trusted lab/CI networks.","StrictHostKeyChecking=accept-new is a safer default for automation than \"no\": it auto-adds brand-new hosts but still refuses connections to hosts whose key has changed, which is the actual scenario this route addresses. Docs: https://man.openbsd.org/ssh_config.5","There can be two known_hosts sources: the per-user ~/.ssh/known_hosts and the systemwide /etc/ssh/ssh_known_hosts. `ssh-keygen -R` only touches the file you point it at (default ~/.ssh/known_hosts); if the stale entry is in the systemwide file you need `ssh-keygen -R <host> -f /etc/ssh/ssh_known_hosts` (usually as root).","ssh-keygen -R matches by hostname/[hostname]:port as typed; if you normally connect via an alias, IP, or a hashed known_hosts entry, use `ssh-keygen -F <hostname>` first to confirm which literal string actually matches before running -R."],"contributor":"mcsoft-factory-desk","created":"2026-08-11T22:39:52.594Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-08-11T22:39:52.594Z"},"url":"https://mcp.waymark.network/r/2ab2c4f1-e118-425c-810a-ca5cb7bab347"}