{"record":{"id":"405de72ad86b1a4a","repo":"denoland/deno","slug":"checksum-mismatch-for-expected-got","errorCode":null,"errorMessage":"Checksum mismatch for {}: expected {}, got {}","messagePattern":"Checksum mismatch for (.+?): expected (.+?), got (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cli/tools/publish/mod.rs","lineNumber":1487,"sourceCode":"  if manifest.manifest.len() != package.tarball.files.len() {\n    bail!(\n      \"Mismatch in the number of files in the manifest: expected {}, got {}\",\n      package.tarball.files.len(),\n      manifest.manifest.len()\n    );\n  }\n\n  for (path, entry) in manifest.manifest {\n    // Verify each path with the files in the tarball.\n    let file = package\n      .tarball\n      .files\n      .iter()\n      .find(|f| f.path_str == path.as_str());\n\n    if let Some(file) = file {\n      if file.hash != entry.checksum {\n        bail!(\n          \"Checksum mismatch for {}: expected {}, got {}\",\n          path,\n          entry.checksum,\n          file.hash\n        );\n      }\n    } else {\n      bail!(\"File {} not found in the tarball\", path);\n    }\n  }\n\n  for (specifier, expected) in &manifest.exports {\n    let actual = package.exports.get(specifier).ok_or_else(|| {\n      deno_core::anyhow::anyhow!(\n        \"Export {} not found in the package\",\n        specifier\n      )\n    })?;","sourceCodeStart":1469,"sourceCodeEnd":1505,"githubUrl":"https://github.com/denoland/deno/blob/f7822238cab635a3a19f99f493f675fa81a7f9d8/cli/tools/publish/mod.rs#L1469-L1505","documentation":"During provenance verification, each file's checksum in the registry's version manifest is compared with the hash of the corresponding file in the tarball Deno prepared. A mismatch means the content JSR recorded differs from what Deno hashed locally — an integrity failure, not a usage error, and a potential supply-chain signal.","triggerScenarios":"`file.hash != entry.checksum` in `verify_version_manifest` — tarball bytes changed between local hashing and server-side ingestion, or the manifest refers to different content (registry bug or tampering).","commonSituations":"Almost always infrastructure-level; surfaces only in provenance-enabled (GitHub Actions + OIDC) publishes.","solutions":["Retry the release — transient ingest errors are the likeliest cause and completed versions are skipped on re-run.","If reproducible, report it at https://github.com/denoland/deno/issues with the package name and version.","Emergency releases can skip verification with `--no-provenance` (accepting a weaker attestation)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"#!/usr/bin/env bash\nout=\"$(deno publish 2>&1)\" || {\n  if printf '%s' \"$out\" | grep -q 'Checksum mismatch'; then\n    echo \"INTEGRITY: uploaded content hash != registry manifest hash — report upstream, investigate before re-release\" >&2\n    exit 71\n  fi\n  printf '%s\\n' \"$out\" >&2; exit 1\n}","preventionTips":["Never ignore checksum mismatches or silence them in CI — they are tamper/ingest signals, not flakiness.","One clean retry is acceptable (transient ingest), but a repeat mismatch should page a human.","Publish releases from reproducible CI (pinned Deno version, clean checkout) so the local hash side is trustworthy."],"tags":["publish","jsr","checksum","integrity","provenance"],"backgroundTag":"checksum-mismatch","analyzedSha":"f7822238cab635a3a19f99f493f675fa81a7f9d8","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}