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
- Re-run the install once; transient truncation is the most common cause
- If the mismatch is reproducible, verify manually: download the artifact with curl and compare `sha256sum` against the digest in the error message
- Exclude registry.nasiko.dev from TLS interception/AV payload scanning, or run from an unrestricted network
- 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
- Exclude the registry origin from TLS-inspecting proxies and AV payload scanning
- Never patch out or bypass the digest check to 'get past' this error
- Log both digests from the message when reporting - they identify exactly which artifact was served
- Retry at most once; deterministic mismatches are an incident, not a flake
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
- Refusing to run install from untrusted repo root ${normalize
- Refusing to replace modified legacy Codex artifact: ${filePa
- Nasiko installation requires a pinned version such as v0.1.0
- Nasiko ${version} is not qualified for ${normalized.os}/${no
AI-assisted analysis of affaan-m/ECC@06c5e118c4 (2026-08-18).
Data as JSON: /api/errors/665aa726c2a27813.
Report an issue: GitHub.