{"record":{"id":"cd6816bf4b503df7","repo":"affaan-m/ECC","slug":"nasiko-manifest-layer-is-not-a-qualified-gzip-arti","errorCode":null,"errorMessage":"Nasiko manifest layer is not a qualified gzip artifact.","messagePattern":"Nasiko manifest layer is not a qualified gzip artifact\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"scripts/lib/nasiko-release.js","lineNumber":68,"sourceCode":"function digestBytes(bytes) {\n  return `sha256:${crypto.createHash('sha256').update(bytes).digest('hex')}`;\n}\n\nfunction assertDigest(bytes, expectedDigest, label) {\n  if (!SHA256_PATTERN.test(expectedDigest)) throw new Error(`${label} has an invalid expected digest.`);\n  const actual = digestBytes(bytes);\n  if (actual !== expectedDigest) throw new Error(`${label} digest mismatch: expected ${expectedDigest}, got ${actual}.`);\n}\n\nfunction validateManifest(bytes) {\n  let manifest;\n  try { manifest = JSON.parse(bytes.toString('utf8')); } catch (_error) { throw new Error('Nasiko manifest is not valid JSON.'); }\n  if (manifest.schemaVersion !== 2 || !Array.isArray(manifest.layers) || manifest.layers.length !== 1) {\n    throw new Error('Nasiko manifest must contain exactly one OCI layer.');\n  }\n  const layer = manifest.layers[0];\n  if (layer.mediaType !== 'application/gzip' || !SHA256_PATTERN.test(layer.digest)) {\n    throw new Error('Nasiko manifest layer is not a qualified gzip artifact.');\n  }\n  if (!Number.isSafeInteger(layer.size) || layer.size <= 0 || layer.size > MAX_ARCHIVE_BYTES) {\n    throw new Error('Nasiko manifest layer size is outside the allowed range.');\n  }\n  return { digest: layer.digest, size: layer.size };\n}\n\nfunction readTarString(block, offset, length) {\n  return block.subarray(offset, offset + length).toString('utf8').replace(/\\0.*$/, '');\n}\n\nfunction readTarOctal(block, offset, length) {\n  const field = block.subarray(offset, offset + length).toString('ascii');\n  const match = /^ *([0-7]+)[ \\0]*$/.exec(field);\n  if (!match) throw new Error('Unsafe Nasiko archive: invalid tar size field.');\n  const size = Number.parseInt(match[1], 8);\n  if (!Number.isSafeInteger(size) || size < 0) {\n    throw new Error('Unsafe Nasiko archive: invalid tar size field.');","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/nasiko-release.js#L50-L86","documentation":"validateManifest requires the single OCI layer to have mediaType 'application/gzip' and a well-formed sha256 digest. This error is thrown when either check fails, meaning the layer is not the qualified gzip artifact the installer knows how to verify and extract.","triggerScenarios":"The manifest's layers[0].mediaType is something else (e.g. application/vnd.oci.image.layer.v1.tar+gzip, application/vnd.docker...tar, or application/octet-stream), or layers[0].digest fails SHA256_PATTERN (wrong prefix, uppercase, truncated).","commonSituations":"Publishing pipeline changed the layer compression or media type, artifact was built with docker instead of the OCI toolchain, or digest format drifted between publisher versions.","solutions":["Inspect layers[0].mediaType and compare against 'application/gzip'; republish the artifact with the required media type if you control the pipeline.","Verify layers[0].digest matches /^sha256:[0-9a-f]{64}$/ and fix the publishing step that emits it.","Confirm you are reading the OCI image manifest, not an index/manifest list whose entry shapes differ.","Use a digest-pinned reference so you get the exact artifact version this library was built for."],"exampleFix":"// before\nvalidateManifest(manifestBytes); // throws: mediaType is tar+gzip\n// after\nconst m = JSON.parse(manifestBytes.toString('utf8'));\nconst layer = m.layers[0];\nif (layer.mediaType !== 'application/gzip') {\n  throw new Error(`republish required: got mediaType ${layer.mediaType}`);\n}\nvalidateManifest(manifestBytes);","handlingStrategy":"validation","validationCode":"const layer = JSON.parse(manifestBytes.toString('utf8')).layers[0];\nif (layer.mediaType !== 'application/gzip' || !/^sha256:[0-9a-f]{64}$/.test(layer.digest)) throw new Error('layer not qualified gzip artifact');","typeGuard":"const isQualifiedGzipLayer = (l) => l?.mediaType === 'application/gzip' && typeof l?.digest === 'string' && /^sha256:[0-9a-f]{64}$/.test(l.digest);","tryCatchPattern":"try { installNasiko(opts); } catch (e) { if (e.message.includes('not a qualified gzip artifact')) console.error('check publisher mediaType settings'); throw e; }","preventionTips":["Publish layers with mediaType application/gzip as the library requires.","Snapshot-test your release manifest against the expected shape.","Avoid generic container build tools that emit tar+gzip media types."],"tags":["oci","media-type","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}