gchq/CyberChef · error · Error

Invalid marker while parsing JPEG at pos ${stream.position}:

Error message

Invalid marker while parsing JPEG at pos ${stream.position}: ${marker}

What it means

Thrown by extractJPEG while walking JPEG segments. Every JPEG marker is two bytes beginning with 0xFF; if the first byte read is not 0xFF the stream is misaligned or the data is not JPEG. This throws a plain Error (not OperationError), so it surfaces as an internal/unexpected failure rather than recipe output.

Source

Thrown at src/core/lib/FileSignatures.mjs:2634

            extractor: null
        }
    ]
};


/**
 * JPEG extractor.
 *
 * @param {Uint8Array} bytes
 * @param {number} offset
 * @returns {Uint8Array}
 */
export function extractJPEG(bytes, offset) {
    const stream = new Stream(bytes.slice(offset));

    while (stream.hasMore()) {
        const marker = stream.getBytes(2);
        if (marker[0] !== 0xff) throw new Error(`Invalid marker while parsing JPEG at pos ${stream.position}: ${marker}`);

        let segmentSize = 0;
        switch (marker[1]) {
            // No length
            case 0xd8: // Start of Image
            case 0x01: // For temporary use in arithmetic coding
                break;
            case 0xd9: // End found
                return stream.carve();

            // Variable size segment
            case 0xc0: // Start of frame (Baseline DCT)
            case 0xc1: // Start of frame (Extended sequential DCT)
            case 0xc2: // Start of frame (Progressive DCT)
            case 0xc3: // Start of frame (Lossless sequential)
            case 0xc4: // Define Huffman Table
            case 0xc5: // Start of frame (Differential sequential DCT)
            case 0xc6: // Start of frame (Differential progressive DCT)

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Confirm the input actually starts with the JPEG SOI marker (0xFFD8) before calling extractJPEG.
  2. Verify the offset points at a real JPEG segment boundary (typically the SOI).
  3. If the file is corrupt, re-acquire it or route it to the correct format extractor.

Example fix

// before
extractJPEG(arbitraryBytes, 0);

// after
if (arbitraryBytes[0] === 0xff && arbitraryBytes[1] === 0xd8) {
    extractJPEG(arbitraryBytes, 0);
}
Defensive patterns

Strategy: validation

Validate before calling

function looksLikeJPEG(bytes, offset = 0) {
  return bytes.length - offset >= 2 && bytes[offset] === 0xff && bytes[offset + 1] === 0xd8;
}
if (!looksLikeJPEG(bytes, offset)) throw new Error("Input is not a JPEG (no SOI marker)");
extractJPEG(bytes, offset);

Type guard

const isJPEGSOI = (bytes, offset = 0) =>
  bytes.length - offset >= 2 && bytes[offset] === 0xff && bytes[offset + 1] === 0xd8;

Try / catch

try {
  extractJPEG(bytes, offset);
} catch (err) {
  if (/Invalid marker while parsing JPEG/.test(err.message)) {
    // not a JPEG or corrupt; route to a different extractor
  } else throw err;
}

Prevention

When it happens

Trigger: Calling extractJPEG(bytes, offset) on data that is not a JPEG, with an offset that lands mid-scan, or on a truncated/corrupted file where segment boundaries are wrong. Note the message interpolates `marker` (a Uint8Array), so the value prints as a comma-separated sequence like '0,1'.

Common situations: Wrong file type routed to the JPEG extractor; offset computed incorrectly by a caller; bit-flipped or crafted/malicious file; truncated download where a segment size jumped past real data.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/b58656b0054b3f20. Report an issue: GitHub.