{"record":{"id":"f35e51569807a288","repo":"gchq/CyberChef","slug":"error-loading-image-err-f35e51","errorCode":null,"errorMessage":"Error loading image. (${err})","messagePattern":"Error loading image\\. \\((.+?)\\)","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/ContainImage.mjs","lineNumber":116,"sourceCode":"\n        const alignMap = {\n            Left: HorizontalAlign.LEFT,\n            Center: HorizontalAlign.CENTER,\n            Right: HorizontalAlign.RIGHT,\n            Top: VerticalAlign.TOP,\n            Middle: VerticalAlign.MIDDLE,\n            Bottom: VerticalAlign.BOTTOM,\n        };\n\n        if (!isImage(input)) {\n            throw new OperationError(\"Invalid file type.\");\n        }\n\n        let image;\n        try {\n            image = await Jimp.read(input);\n        } catch (err) {\n            throw new OperationError(`Error loading image. (${err})`);\n        }\n        const originalMime = image.mime;\n        try {\n            if (isWorkerEnvironment())\n                self.sendStatusMessage(\"Containing image...\");\n            image.contain({\n                w: width,\n                h: height,\n                align: alignMap[hAlign] | alignMap[vAlign],\n                mode: resizeMap[alg],\n            });\n\n            if (opaqueBg) {\n                const newImage = new Jimp({\n                    width,\n                    height,\n                    color: 0x000000ff,\n                });","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/ContainImage.mjs#L98-L134","documentation":"After isImage() confirms the bytes look like a supported image, Contain Image calls Jimp.read(input) to decode the pixels. If decoding fails — corrupt or truncated payload, a header that matches but a body Jimp cannot parse, or a format this Jimp version lacks a codec for — the thrown error is wrapped as 'Error loading image.' So the magic-byte check passed but the actual decode did not.","triggerScenarios":"Truncated download (header present, body cut off); valid magic bytes but structurally corrupt image; a color space or sub-format Jimp cannot decode (e.g. CMYK JPEG, 16-bit PNG); Jimp version mismatch where isImage detects a type Jimp can't read.","commonSituations":"Partial file transfer; re-saving from a tool that emitted an exotic variant; dependency upgrade changing Jimp's supported format set; animated/multi-frame containers.","solutions":["Re-export or re-save the source image in a standard format (PNG or baseline JPEG) using an image editor.","Verify file integrity (complete download, correct byte length).","Check the Jimp version bundled with this CyberChef build for the supported codec list.","If the format is exotic, transcode it to PNG externally first."],"exampleFix":"// before: truncated PNG (header ok, IDAT missing)\n// after: supply the complete, valid PNG file bytes","handlingStrategy":"try-catch","validationCode":"import { isImage } from \"src/core/lib/FileType.mjs\";\n// Reduces (not eliminates) the chance: isImage must pass before Jimp.read is attempted.\nconst bytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input;\nif (!isImage(bytes)) {\n  throw new Error(\"Not a recognized image — Jimp.read would likely fail.\");\n}","typeGuard":"import { isImage } from \"src/core/lib/FileType.mjs\";\nfunction isLikelyDecodableImage(buf) {\n  const bytes = buf instanceof ArrayBuffer ? new Uint8Array(buf) : buf;\n  return isImage(bytes) !== false;\n}","tryCatchPattern":"try {\n  result = await containImage.run(input, args);\n} catch (err) {\n  if (/Error loading image/.test(err.message)) {\n    // isImage passed but Jimp decode failed: source is corrupt/truncated or an unsupported sub-format.\n    // Re-export the source as PNG/baseline JPEG externally, then retry.\n  }\n  throw err;\n}","preventionTips":["isImage passing does not guarantee Jimp can decode — validate file integrity separately.","Prefer standard PNG or baseline JPEG sources to avoid sub-format decode gaps.","After a dependency/Jimp upgrade, re-test the formats you rely on."],"tags":["cyberchef","image","jimp","decode","operation-error"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}