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

  1. Delete the cached download and re-download — transient corruption is the most common cause.
  2. 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.
  3. Download from an official source or a different mirror if a proxy is altering content.
  4. 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

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


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)