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

checksum for `{}` changed between lock files this could be

Error message

checksum for `{}` changed between lock files

this could be indicative of a few possible errors:

    * the lock file is corrupt
    * a replacement source in use (e.g., a mirror) returned a different checksum
    * the source itself may be corrupt in one way or another

unable to verify that `{0}` is the same as when the lockfile was generated

What it means

Both previous and current checksums are `Some` but differ — the package's checksum changed between the locked value and what the current source reports. This is the most serious checksum case: it means the package bytes the Cargo is about to use are not provably the same as what the lockfile pinned, indicating corruption, a divergent mirror, or source tampering.

Source

Thrown at src/resolver/resolve.rs:280

the existing lock file

this could be indicative of a few possible situations:

    * the source `{}` supports checksums,
      but was replaced with one that doesn't
    * the lock file is corrupt

unable to verify that `{0}` is the same as when the lockfile was generated
",
                        id,
                        id.source_id()
                    )

                // If the checksums aren't equal, and neither is None, then they
                // must both be Some, in which case the checksum now differs.
                // That's quite bad!
                } else {
                    anyhow::bail!(
                        "\
checksum for `{}` changed between lock files

this could be indicative of a few possible errors:

    * the lock file is corrupt
    * a replacement source in use (e.g., a mirror) returned a different checksum
    * the source itself may be corrupt in one way or another

unable to verify that `{0}` is the same as when the lockfile was generated
",
                        id
                    );
                }
            }
        }

        // Be sure to just copy over any unknown metadata.

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Clear the local registry cache: `cargo cache -a` or delete `~/.cargo/registry/cache` and `src`, then re-fetch.
  2. Remove or fix the `[source]` replacement / mirror that is serving divergent content.
  3. Regenerate the lockfile (`cargo generate-lockfile`) only after confirming the source is trustworthy.
  4. Compare the actual checksum against crates.io to determine whether the source or the lockfile is the mutated side.

Example fix

# before: mirror serves altered artifact
rm -rf ~/.cargo/registry/cache ~/.cargo/registry/src
cargo generate-lockfile
cargo build
Defensive patterns

Strategy: try-catch

Validate before calling

# In CI, pin and verify registry checksums before building:
cargo fetch --locked || { echo 'checksum mismatch — possible mirror/cache corruption'; exit 1; }

Try / catch

// In a wrapping build script:
let out = std::process::Command::new("cargo").args(["build","--locked"]).output()?;
if !out.status.success() {
    let s = String::from_utf8_lossy(&out.stderr);
    if s.contains("checksum") && s.contains("changed between lock files") {
        eprintln!("Checksum divergence detected — clear ~/.cargo/registry and verify mirror.");
    }
    return Err(anyhow::anyhow!("cargo build failed"));
}

Prevention

When it happens

Trigger: A mirror/replacement source returns different content (hence different checksum) than crates.io recorded in `Cargo.lock`; a corrupted registry cache; a yanked-and-republished crate; man-in-the-middle or storage corruption. The final `else` branch in the checksum comparison fires.

Common situations: Using a crates.io mirror or proxy that serves slightly different artifacts; corrupted `~/.cargo/registry/cache`; a `[patch]`/`[replace]` overriding a crate with content that doesn't match the locked checksum; disk/filesystem corruption.

Related errors


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