ECDSA Keys Changed, SSH insecure now?

  • I'm running some non-critical Ubuntu servers in my dorm room in college. Turned them off before break, come back, SSH in, and get a warning that the ECDSA keys have changed.

    It looked pretty much like this

    Warning: the ECDSA host key for '<snip>' differs from the key for the IP address '<snip>'
    Offending key for IP in /home/<snip>/.ssh/known_hosts:14
    Matching host key in /home/<snip>/.ssh/known_hosts:12
    Are you sure you want to continue connecting (yes/no)?

    This looks a lot less scary than the server identity changed error so I'm not worrying too much but still, what would cause this to change? Is this something I should be worrying about?

  • When you connect first time to a given SSH server, you get the usual question with the key fingerprint; afterwards, the SSH client stores a copy of the server public key in the .ssh/known_hosts file. But the SSH client actually stores two keys: one for the server name, and one for the server IP.

    For instance, assume that server has IP Upon your first connection (ssh, the SSH client will get the server public key, display the fingerprint (a hash of the public key), ask for confirmation, and then store in the known_hosts file two mappings, one for, the other for, both pointing to the same public key.

    When you connect back to the same server, SSH verifies the two mappings. If the first mapping (the one for the name) yields a public key that is distinct from the one recorded in known_hosts, you get the scary error message with UPPERCASE LETTERS (that's how it manages to be scary), and the client refuses to connect any further (so the message is not only scary, it is quite inconvenient as well).

    Another situation is when the first mapping matches:

    • The user types: ssh
    • The DNS system resolves that name to IP
    • The SSH client connects to that machine, and obtains the SSH server public key.
    • The obtained public key matches the one found in .ssh/known_hosts under the entry
    • BUT the obtained public key does NOT match the one found in .ssh/known_hosts under the entry

    In that case, you get the exact message that you display in your question. The SSH client has some assurance that you are talking to the intended server -- the public key matches the one recorded for the same server name -- but something is still amiss, hence the warning, and the confirmation prompt.

    This can happen when the server IP has changed. With the example above, suppose that, last week, had IP, but had IP At that time, you connected to both. But last week-end, a sysadmin with slight obsessional compulsive disorder decided that some IP had to be changed, so that he could setup more efficient, regular and mathematically elegant networking rules. So he "moved servers around", and set to IP and to Our friend the sysadmin dutifully configured the DNS to report the new IP. Now, we are on Monday, and you want to connect again. Your SSH client talks to the DNS, gets the new IP for, and all is fine, except that the recorded key for does not match the public key of indeed, your known_hosts file contains a copy of the public key of, listed under the IP, which, up to last week, was bar's IP, not foo's.

    A sysadmin with OCD is not strictly necessary for this scenario; it can also happen with dynamic IP setups, or with some cases of load-balancing.

    Solution: use a text editor and remove the offending entry from your known_hosts (line 14, in your case). You can also use the command ssh-keygen -R <host> to remove the particular entry. Next time you will connect, the client will display yet another warning (this time complaining about the absence of any recorded public key for the target IP), but this one will fly by almost unnoticed, because there will be no prompt at all. The SSH client will then record the public key again in known_hosts, and set things right, at least until the sysadmin hear voices again.

    Alternatively, disable host IP checking in the SSH client, by setting the option CheckHostIP to no (in the system-wide /etc/ssh/ssh_config, or your .ssh/config, or directly on the command-line: ssh -o CheckHostIP=no Host-IP checks are useful to detect abnormal situations of wandering server names, but for some sysadmins, server IP jugglery is perfectly "normal".

  • Assuming I am guessing the <snip> parts correctly, looks like the hostname ( is now resolving to a different IP than it was before.

    Whether or not you need to worry about that is difficult to tell without more information. What form is the hostname? Is it an FQDN? Is it resolved using DNS? Did you make any DNS changes? That kind of information.

    It's probably better if you replace your hostnames and IPs with examples (,, and anything-you-want.test are good for hostnames, private IPs like or are good for IPs), that way the command output is easier to interpret. You can also use this to indicate whether two domains are in the same TLD, whether two IPs are in the same subnet, etc. so it's very useful.

  • If the IP wasn't moved and the openssh-server package wasn't upgraded and a new host key generated, then what happened?

    While you can disable the host key check, this isn't a practice I would start.

    What seems to have happened is that ssh is now using a different host key system (ECDSA vs DSA or RSA) and the warning is making us aware of that.

    This change could have occurred in a recent upgrade of openssh-server.

License under CC-BY-SA with attribution

Content dated before 7/24/2021 11:53 AM

Tags used