rust-lang/cargo · critical · anyhow::Error

error: SSH host key has changed for `{hostname}` ***********

Error message

error: SSH host key has changed for `{hostname}`
*********************************
* WARNING: HOST KEY HAS CHANGED *
*********************************
This may be caused by a man-in-the-middle attack, or the server may have changed its host key.

The {key_type_short_name} fingerprint for the key from the remote host is:
    SHA256:{remote_fingerprint}

You are strongly encouraged to contact the server administrator for `{hostname}` to verify that this new key is correct.

If you can verify that the server has a new key, you can resolve this error by {old_key_resolution}

The key provided by the remote host is:

{hostname} {key_type_name} {remote_host_key}

See https://doc.rust-lang.org/stable/cargo/appendix/git-authentication.html#ssh-known-hosts for more information.

What it means

Security-critical: the SSH host key for `hostname` matches a known_hosts entry by host but the key itself differs from what was previously recorded. This is the classic man-in-the-middle indicator — either an attacker is intercepting the connection, or the server legitimately rotated its key. Cargo surfaces a prominent warning and refuses to proceed until the old key is removed and the new one verified.

Source

Thrown at src/sources/git/known_hosts.rs:264

                        located at {old_key_location} line {lineno}, \
                        and adding the new key to {known_hosts_location}",
                    )
                }
                KnownHostLocation::Config { definition } => {
                    format!(
                        "removing the old {key_type_name} key for `{hostname}` \
                        loaded from Cargo's config at {definition}, \
                        and adding the new key to {known_hosts_location}"
                    )
                }
                KnownHostLocation::Bundled => {
                    format!(
                        "adding the new key to {known_hosts_location}\n\
                        The current host key is bundled as part of Cargo."
                    )
                }
            };
            anyhow::bail!(
                "error: SSH host key has changed for `{hostname}`\n\
                *********************************\n\
                * WARNING: HOST KEY HAS CHANGED *\n\
                *********************************\n\
                This may be caused by a man-in-the-middle attack, or the \
                server may have changed its host key.\n\
                \n\
                The {key_type_short_name} fingerprint for the key from the remote host is:\n\
                    SHA256:{remote_fingerprint}\n\
                \n\
                You are strongly encouraged to contact the server \
                administrator for `{hostname}` to verify that this new key is \
                correct.\n\
                \n\
                If you can verify that the server has a new key, you can \
                resolve this error by {old_key_resolution}\n\
                \n\
                The key provided by the remote host is:\n\

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Contact the server administrator and verify the new SHA256 fingerprint is legitimate BEFORE trusting it.
  2. Once verified, remove the old key line (location given in `old_key_resolution`) from `~/.ssh/known_hosts` or Cargo config, then add the new key (reconnect or use `ssh-keyscan`).
  3. If unintentional, treat as a security incident — investigate for MITM before changing anything.
  4. For legitimate rotation, communicate the new fingerprint to all developers/CI to update their known_hosts.

Example fix

# before: stale known_hosts entry causes refusal
ssh-keygen -R example.com
ssh-keyscan example.com >> ~/.ssh/known_hosts
cargo fetch
Defensive patterns

Strategy: validation

Validate before calling

# Before connecting, confirm the remote key matches the recorded one:
ssh-keygen -F example.com -f ~/.ssh/known_hosts  # shows stored key
ssh-keyscan example.com | ssh-keygen -l -f -      # shows remote fingerprint
# Compare fingerprints; only proceed if they match (or rotation is confirmed).

Prevention

When it happens

Trigger: The `HostKeyHasChanged` variant: the server's host key no longer matches the one stored in known_hosts/Cargo config. Common after server reinstall, key rotation, or IP/DNS repointing to a different host. Also the expected signal of an active MITM attack.

Common situations: Git server migrated/reinstalled (new host key); load balancer routing to a host with a different key; corporate proxy/MITM; compromised key being replaced; stale known_hosts after infrastructure change.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/52a6e6c3e9802163.json. Report an issue: GitHub.