denoland/deno · critical · AnyError

Checksum verification failed. Actual: {} Expected: {}

Error message

Checksum verification failed.
  Actual:   {}
  Expected: {}

What it means

Every downloaded upgrade archive is verified against its published SHA-256 checksum (`*.sha256` file). This error means the hex digest of the downloaded bytes did not match the expected value, so the archive is corrupt or was altered, and Deno refuses to install it. Note: in current code the two labels are swapped — the value printed as 'Actual' is the expected checksum string and 'Expected' is the locally computed digest — so read the pair as 'published vs computed'.

Source

Thrown at cli/tools/upgrade.rs:1910

  // text above which will stay alive after the progress bars are complete
  let progress = progress_bar.update("");
  let response = client
    .download_with_progress_and_retries(download_url.clone(), &Default::default(), &progress)
    .await
    .with_context(|| format!("Failed downloading {download_url}. The version you requested may not have been built for the current architecture."))?;
  Ok(response.into_maybe_bytes()?)
}

fn verify_checksum(
  data: &[u8],
  expected_checksum: &str,
) -> Result<(), AnyError> {
  let computed = sha2::Sha256::digest(data);
  let computed_hex = faster_hex::hex_string(&computed);

  let expected_checksum = expected_checksum.trim().to_lowercase();
  if computed_hex != expected_checksum {
    bail!(
      "Checksum verification failed.\n  Actual:   {}\n  Expected: {}",
      expected_checksum,
      computed_hex
    );
  }

  log::info!("{}", colors::gray("Checksum verified"));
  Ok(())
}

fn replace_exe(from: &Path, to: &Path) -> Result<(), std::io::Error> {
  if cfg!(windows) {
    // On windows you cannot replace the currently running executable.
    // so first we rename it to deno.old.exe
    fs::rename(to, to.with_extension("old.exe"))?;
  } else {
    fs::remove_file(to)?;
  }

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Re-run `deno upgrade` — most checksum failures are truncated transfers that a fresh download fixes.
  2. If it persists, download the archive manually, verify its sha256 against the published `.sha256` file, and install by hand.
  3. Disable/inspect HTTP-altering proxies, VPNs, or antivirus HTTPS inspection for dl.deno.dev.
  4. Report it if a manual download also mismatches the published checksum (publishing-side issue).

Example fix

# before
deno upgrade  # Checksum verification failed. Actual: ... Expected: ...

# after: manual verify + install
curl -O https://dl.deno.land/release/v1.44.0/deno-x86_64-unknown-linux-gnu.zip
curl -O https://dl.deno.land/release/v1.44.0/deno-x86_64-unknown-linux-gnu.zip.sha256
sha256sum -c deno-x86_64-unknown-linux-gnu.zip.sha256  # then unzip to your install dir
Defensive patterns

Strategy: retry

Validate before calling

# verify manually before upgrading (mirrors the internal check)
url=https://dl.deno.land/release/v1.44.0/deno-x86_64-unknown-linux-gnu.zip
curl -fsS -o d.zip "$url" && curl -fsS -o d.zip.sha256 "$url.sha256"
echo "$(cat d.zip.sha256)  d.zip" | sha256sum -c - || echo "corrupt source — do not install"

Try / catch

for i in 1 2 3; do deno upgrade && break || { echo "checksum failed — retry $i"; sleep 10; }; done

Prevention

When it happens

Trigger: Truncated/corrupted download (dropped connection, proxy mangling bytes); a CDN/mirror serving stale or wrong archive for the version's checksum; disk corruption; theoretically a tampered download. Comparison happens after lowercasing/trimming the expected value at cli/tools/upgrade.rs:1910.

Common situations: Flaky networks or corporate proxies that modify HTTPS bodies; system clocks/antivirus interfering with the download; downloading a version whose archive was re-uploaded with a different checksum.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/f342b745cfe56fe1. Report an issue: GitHub.