mozilla/pdf.js · warning · DNLMarkerError
Found EOI marker (0xFFD9) while parsing scan data, possibly
Error message
Found EOI marker (0xFFD9) while parsing scan data, possibly caused by incorrect `scanLines` parameter
What it means
Thrown as DNLMarkerError when an EOI (0xFFD9) marker ends the scan and a heuristic detects the declared frame.scanLines is far larger (>= 5x) than the lines actually parsed (maybeScanLines). pdf.js uses this to recover by substituting the parsed line count, fixing corrupt JPEGs with an oversized height. Only thrown when parseDNLMarker is true.
Source
Thrown at src/core/jpg.js:175
throw new DNLMarkerError(
"Found DNL marker (0xFFDC) while parsing scan data",
scanLines
);
}
} else if (nextByte === /* EOI = */ 0xd9) {
if (parseDNLMarker) {
// NOTE: only 8-bit JPEG images are supported in this decoder.
const maybeScanLines = blockRow * (frame.precision === 8 ? 8 : 0);
// Heuristic to attempt to handle corrupt JPEG images with too
// large `scanLines` parameter, by falling back to the currently
// 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;View on GitHub (pinned to 5903d58d58)
Solutions
- Allow pdf.js to recover: DNLMarkerError.scanLines carries the corrected count and is handled internally — do not rethrow it as fatal in a custom decoder wrapper.
- Re-encode the offending JPEG so its SOF height equals the true pixel height.
- Rebuild the PDF with corrected image dimensions to avoid the mismatch.
- If invoking the decoder directly with parseDNLMarker=false, the EOI will instead raise EOIMarkerError (see error 158).
Defensive patterns
Strategy: try-catch
Validate before calling
// Heuristic mirroring pdf.js: flag JPEGs whose declared height is implausible.
function jpegHeightLikelyOversized(declaredScanLines, plausibleScanLines) {
return plausibleScanLines > 0 &&
Math.round(declaredScanLines / plausibleScanLines) >= 5;
} Type guard
function isRecoverableEoiDnlError(err) {
return err?.name === 'DNLMarkerError' && typeof err.scanLines === 'number' &&
err.scanLines > 0;
} Try / catch
// Let pdf.js recover; if wrapping the decoder directly:
try { decodeScan(...); }
catch (err) {
if (err?.name === 'DNLMarkerError') {
frame.scanLines = err.scanLines;
} else if (err?.name === 'EOIMarkerError') {
throw err; // unrecoverable
} else throw err;
} Prevention
- Do not unwrap DNLMarkerError as fatal; use err.scanLines to recover.
- Re-encode JPEGs so SOF height matches the real line count.
- Keep parseDNLMarker=true (default) to benefit from recovery.
When it happens
Trigger: Decoding a JPEG whose SOF height is wildly larger than the real image, the scan ends with EOI, and maybeScanLines (blockRow*8 for 8-bit) is at least 5x smaller than frame.scanLines. Triggered by DCTDecode image rendering of such corrupt streams.
Common situations: The classic pdf.js regressions issue10880.pdf, issue10989.pdf, issue15492.pdf; any JPEG whose declared height was padded/inflated and never corrected by a DNL marker.
Related errors
- Found DNL marker (0xFFDC) while parsing scan data
- Found EOI marker (0xFFD9) while parsing scan data
- unexpected marker ${((bitsData << 8) | nextByte).toString(16
- 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/90c44af6b32d9178.
Report an issue: GitHub.