mozilla/pdf.js · error · JpegError
unexpected marker ${((bitsData << 8) | nextByte).toString(16
Error message
unexpected marker ${((bitsData << 8) | nextByte).toString(16)} What it means
Thrown as JpegError when readBit encounters a non-zero byte after 0xFF that is neither DNL (0xDC) nor EOI (0xD9) — i.e. an unexpected JPEG marker embedded inside the scan data. The scan bit-stream should only ever byte-stuff 0xFF00; any other marker is invalid mid-scan.
Source
Thrown at src/core/jpg.js:186
// parsed number of scanLines when it's at least (approximately)
// one "half" order of magnitude smaller than expected (fixes
// issue10880.pdf, issue10989.pdf, issue15492.pdf).
if (
maybeScanLines > 0 &&
Math.round(frame.scanLines / maybeScanLines) >= 5
) {
throw new DNLMarkerError(
"Found EOI marker (0xFFD9) while parsing scan data, " +
"possibly caused by incorrect `scanLines` parameter",
maybeScanLines
);
}
}
throw new EOIMarkerError(
"Found EOI marker (0xFFD9) while parsing scan data"
);
}
throw new JpegError(
`unexpected marker ${((bitsData << 8) | nextByte).toString(16)}`
);
}
// unstuff 0
}
bitsCount = 7;
return bitsData >>> 7;
}
function decodeHuffman(tree) {
let node = tree;
while (true) {
node = node[readBit()];
switch (typeof node) {
case "number":
return node;
case "object":
continue;View on GitHub (pinned to 5903d58d58)
Solutions
- Re-encode the source JPEG with a standard encoder to eliminate stray markers.
- Validate the JPEG with jpegtran/djpeg before embedding to catch structural errors.
- Catch JpegError at render time and substitute a placeholder image.
- Regenerate the PDF with a known-good image and re-render.
Defensive patterns
Strategy: try-catch
Validate before calling
// No general pre-check; you can scan for stray markers mid-scan, but it is
// expensive. As a sanity gate, confirm the stream starts with SOI (0xFFD8):
function jpegHasSoi(bytes) {
return bytes instanceof Uint8Array && bytes.length >= 2 &&
bytes[0] === 0xff && bytes[1] === 0xd8;
} Type guard
function isJpegError(err) {
return err?.name === 'JpegError' && /unexpected marker/.test(err?.message || '');
} Try / catch
try { await page.render({ canvasContext }).promise; }
catch (err) {
if (err?.name === 'JpegError' && /unexpected marker/.test(err.message)) {
console.warn('Corrupt JPEG marker; substituting placeholder image.');
} else throw err;
} Prevention
- Re-encode JPEGs with a standard encoder (libjpeg/mozjpeg) before embedding.
- Validate with jpegtran -copy none to detect structural issues.
- Catch JpegError at render time and substitute a fallback image.
When it happens
Trigger: Decoding a JPEG whose scan data contains a stray marker (e.g. 0xFFC0-style restart/SOF marker) at a position where a stuffed byte or entropy data was expected. Reached during DCTDecode image rendering of a corrupt or non-conformant JPEG.
Common situations: Truncated/concatenated JPEGs, restart markers in the wrong place, JPEGs damaged by a copy/merge, or streams produced by encoders that emit non-standard markers mid-scan.
Related errors
- Found DNL marker (0xFFDC) while parsing scan data
- Found EOI marker (0xFFD9) while parsing scan data, possibly
- Found EOI marker (0xFFD9) while parsing scan data
- Parent must be a dictionary.
- Kids must be an array.
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/ddf9f43f01ceb9c3.
Report an issue: GitHub.