affaan-m/ECC · critical

${label} digest mismatch: expected ${expectedDigest}, got ${

Error message

${label} digest mismatch: expected ${expectedDigest}, got ${actual}.

What it means

assertDigest in scripts/lib/nasiko-release.js computes sha256 over the downloaded bytes and compares them to the digest pinned in QUALIFIED_RELEASES for either the OCI manifest or the extracted binary. A mismatch aborts the install before anything is executed or written. This is the supply-chain integrity gate: it catches corrupted downloads, proxy/AV tampering, registry serving wrong content, and actual attacks.

Source

Thrown at scripts/lib/nasiko-release.js:57

function getQualifiedRelease(version, platform = process.platform, architecture = process.arch) {
  if (!/^v\d+\.\d+\.\d+$/.test(String(version || ''))) {
    throw new Error('Nasiko installation requires a pinned version such as v0.1.0; latest is not allowed.');
  }
  const normalized = normalizePlatform(platform, architecture);
  const qualification = QUALIFIED_RELEASES[version]?.[`${normalized.os}/${normalized.arch}`];
  if (!qualification) throw new Error(`Nasiko ${version} is not qualified for ${normalized.os}/${normalized.arch}.`);
  return { version, ...normalized, ...qualification, license: LICENSE, sourceUrl: SOURCE_URL };
}

function digestBytes(bytes) {
  return `sha256:${crypto.createHash('sha256').update(bytes).digest('hex')}`;
}

function assertDigest(bytes, expectedDigest, label) {
  if (!SHA256_PATTERN.test(expectedDigest)) throw new Error(`${label} has an invalid expected digest.`);
  const actual = digestBytes(bytes);
  if (actual !== expectedDigest) throw new Error(`${label} digest mismatch: expected ${expectedDigest}, got ${actual}.`);
}

function validateManifest(bytes) {
  let manifest;
  try { manifest = JSON.parse(bytes.toString('utf8')); } catch (_error) { throw new Error('Nasiko manifest is not valid JSON.'); }
  if (manifest.schemaVersion !== 2 || !Array.isArray(manifest.layers) || manifest.layers.length !== 1) {
    throw new Error('Nasiko manifest must contain exactly one OCI layer.');
  }
  const layer = manifest.layers[0];
  if (layer.mediaType !== 'application/gzip' || !SHA256_PATTERN.test(layer.digest)) {
    throw new Error('Nasiko manifest layer is not a qualified gzip artifact.');
  }
  if (!Number.isSafeInteger(layer.size) || layer.size <= 0 || layer.size > MAX_ARCHIVE_BYTES) {
    throw new Error('Nasiko manifest layer size is outside the allowed range.');
  }
  return { digest: layer.digest, size: layer.size };
}

View on GitHub (pinned to 06c5e118c4)

Solutions

  1. Re-run the install once; transient truncation is the most common cause
  2. If the mismatch is reproducible, verify manually: download the artifact with curl and compare `sha256sum` against the digest in the error message
  3. Exclude registry.nasiko.dev from TLS interception/AV payload scanning, or run from an unrestricted network
  4. If the manual hash confirms the registry content differs from the pinned digest, stop and report it to the maintainers - do not bypass the check
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await installNasiko({ version: 'v0.1.0' });
} catch (error) {
  if (/digest mismatch/.test(String(error.message))) {
    // Fail closed: delete partial downloads, never skip verification.
    // One retry covers transient corruption; a repeat mismatch means proxy/AV
    // interference or a supply-chain incident - capture expected/got digests
    // and report upstream.
  }
  throw error;
}

Prevention

When it happens

Trigger: The bytes fetched from registry.nasiko.dev hash differently than the pinned manifestDigest or binaryDigest for the qualified release: a truncated or corrupted HTTP response, a TLS-inspecting corporate proxy or antivirus rewriting content, a transparent captive portal, the registry serving an incorrect artifact, or genuine tampering.

Common situations: Corporate networks with SSL inspection (Zscaler, Blue Coat) mangling binary downloads; flaky CI networks producing truncated bodies; antivirus HTTP scanning modifying payloads; an upstream re-publish of the same tag (which should be treated as an incident).

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 affaan-m/ECC@06c5e118c4 (2026-08-18). Data as JSON: /api/errors/665aa726c2a27813. Report an issue: GitHub.