jdx/mise · error
Checksum mismatch for file
Error message
Checksum mismatch for file {}:
Expected: {algo}:{checksum}
Actual: {algo}:{actual} What it means
ensure_checksum compares the file's computed digest against the expected value; on mismatch it bails with a message showing the expected and actual digests side by side. This guards against corrupted or tampered downloads.
Solutions
- Delete the cached download and re-download — transient corruption is the most common cause.
- Compare the printed Expected/Actual digests; if the actual is stable across redownloads, update your pinned checksum to the new value after verifying it against upstream.
- Download from an official source or a different mirror if a proxy is altering content.
- Verify you pinned the digest for the exact artifact (same version/platform), not a sibling file.
Example fix
// before (stale pinned digest after upstream re-released) checksum = "sha256:deadbeef..." // after re-downloading and verifying upstream digest checksum = "sha256:9f2c1a..."
Defensive patterns
Strategy: retry
Validate before calling
actual=$(sha256sum "$file" | cut -d' ' -f1)
[ "$actual" = "${expected#sha256:}" ] || { rm -f "$file"; exit 1; } Prevention
- Re-download on mismatch before changing any pinned value
- Verify new digests against upstream release pages, never copy from the failed-download output
- Pin digests for the exact artifact filename/version you install
When it happens
Trigger: ensure_checksum is called with a checksum that doesn't match the actual file contents — the file on disk differs from the recorded digest for the same algorithm.
Common situations: Interrupted or proxied download corrupting the artifact; upstream replaced a release artifact (rare but happens) invalidating pinned checksums; editing a file after checksum was recorded; wrong checksum copied from release notes (e.g. digest of a different platform's tarball).
Understand the failure class
Background: Checksum mismatch errors: "checksum verification failed", "digest mismatch", "expected vs actual checksum" — what they mean and how to fix them — this error's family across 41 libraries.
Related errors
- # : sha256 mismatch (expected # , got # )
- Size mismatch for : expected , got
- brew-cask: : cask metadata has no sha256
- : sha256 is , the packslip says
- remote cache action bytes do not match cache key
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/ba932ed368d92af6.
Report an issue: GitHub.
Appendix: source
Thrown at src/hash.rs:134
let out = cmd!("sha1sum", path).read()?;
out.split_whitespace().next().unwrap().to_string()
} else {
file_hash_prog::<Sha1>(path, pr)?
}
}
"md5" => {
if use_external_hasher && file::which("md5sum").is_some() {
let out = cmd!("md5sum", path).read()?;
out.split_whitespace().next().unwrap().to_string()
} else {
file_hash_prog::<Md5>(path, pr)?
}
}
_ => bail!("Unknown checksum algorithm: {}", algo),
};
let checksum = checksum.to_lowercase();
if actual != checksum {
bail!(
"Checksum mismatch for file {}:\nExpected: {algo}:{checksum}\nActual: {algo}:{actual}",
display_path(path)
);
}
Ok(())
}
pub(crate) fn parse_shasums(text: &str) -> HashMap<String, String> {
text.lines()
.filter_map(|l| {
let mut parts = l.split_whitespace();
let hash = parts.next()?;
let name = parts.next()?;
// Strip coreutils binary-mode marker (e.g. "<hash> *file.tar.gz").
let name = name.strip_prefix('*').unwrap_or(name);
Some((name.into(), hash.into()))
})
.collect()View on GitHub (pinned to 533346cc37)