AutoDarkMode/Windows-Auto-Night-Mode · critical · anyhow::Error
sha256 mismatch: expected {:x?}, got {:x?}
Error message
sha256 mismatch: expected {:x?}, got {:x?} What it means
Returned by verify_sha256 when the SHA-256 of the downloaded installer file does not equal the expected hash fetched from the .sha256 sidecar. On mismatch the downloaded file is deleted (remove_file) and the error is bailed, contributing to exit code ERR_VERIFY (13371). This is the integrity check that guards against corrupted or tampered downloads.
Source
Thrown at adm-downloader-rs/src/main.rs:193
let mut f = File::open(path)?;
let mut hasher = Sha256::new();
let mut buf = [0u8; 8192];
loop {
let n = f.read(&mut buf)?;
if n == 0 {
break;
}
hasher.update(&buf[..n]);
}
Ok(hasher.finalize().to_vec())
}
fn verify_sha256(url: &str, path: &PathBuf) -> anyhow::Result<()> {
let expected = fetch_expected_sha256(url)?;
let actual = compute_file_sha256(path)?;
if expected != actual {
let _ = remove_file(path);
anyhow::bail!(
"sha256 mismatch: expected {:x?}, got {:x?}",
expected,
actual
);
}
Ok(())
}
/// run the main download/verify/install flow. The installer's exit code (if run)
/// is written into `installer_code`. On failure this returns one of the
/// explicit error codes (ERR_DOWNLOAD, ERR_VERIFY, ERR_INSTALL_SPAWN).
fn run_install_flow(
url: &str,
temp_path: &PathBuf,
installer_code: &mut Option<i32>,
) -> Result<(), i32> {
// download
if let Err(e) = download_file(url, temp_path) {
View on GitHub (pinned to c15b28e921)
Solutions
- Re-download from a clean network path (no proxy/AV interference) and re-verify.
- Confirm the asset URL and the .sha256 URL reference the exact same release/build.
- Temporarily disable AV real-time scanning of the temp directory during download+verify.
- If the mismatch persists across retries, treat the release as compromised and pin to a known-good version.
- Compare the printed expected vs. got hashes against the project's published checksums manually.
Defensive patterns
Strategy: validation
Validate before calling
// (Defense is the check itself.) Re-verify after a clean re-download:
fn reverify(url: &str, path: &PathBuf) -> anyhow::Result<()> {
let expected = fetch_expected_sha256(url)?;
let actual = compute_file_sha256(path)?;
if expected != actual { anyhow::bail!("sha256 mismatch"); }
Ok(())
} Try / catch
// run_install_flow maps verify failures to ERR_VERIFY. On mismatch the file
// is already deleted; surface a clear message and allow a fresh re-download:
if let Err(e) = verify_sha256(url, temp_path) {
eprintln!("verify failed: {}", e);
// optionally retry the whole download once before returning ERR_VERIFY
return Err(ERR_VERIFY);
} Prevention
- Download over a clean, unproxied connection and re-verify before running the installer.
- Ensure the asset URL and the .sha256 URL reference the same release/build.
- Exclude the temp download directory from AV real-time scanning that could alter the EXE.
- Treat persistent mismatches as a potential compromise — pin to a known-good release.
- Manually compare the expected vs. got hashes against the project's published checksums.
When it happens
Trigger: verify_sha256(url, path): fetch_expected_sha256(url) returns expected bytes; compute_file_sha256(path) hashes the downloaded file in 8KB chunks; expected != actual triggers the bail at line 193 and remove_file.
Common situations: The download was truncated or corrupted by a network error/proxy; the .sha256 file corresponds to a different version/build than the asset URL; a MITM or compromised mirror altered the installer; antivirus modified the EXE after write; disk corruption; the hardcoded base URL and the checksum file drifted out of sync after a re-release.
Related errors
AI-assisted analysis of AutoDarkMode/Windows-Auto-Night-Mode@c15b28e921 (2026-08-13).
Data as JSON: /api/errors/f62db4f615e2f124.
Report an issue: GitHub.