mozilla/pdf.js · warning · DNLMarkerError
Found DNL marker (0xFFDC) while parsing scan data
Error message
Found DNL marker (0xFFDC) while parsing scan data
What it means
Thrown as DNLMarkerError during JPEG scan parsing when a 0xFFDC (DNL - Define Number of Lines) marker is encountered inside the scan data and the scanLines it declares differs from the frame's expected scanLines. pdf.js treats this as a recoverable signal to redefine the image height. Note: parseDNLMarker must be true for this branch.
Source
Thrown at src/core/jpg.js:157
let bitsData = 0,
bitsCount = 0;
function readBit() {
if (bitsCount > 0) {
bitsCount--;
return (bitsData >> bitsCount) & 1;
}
bitsData = data[offset++];
if (bitsData === 0xff) {
const nextByte = data[offset++];
if (nextByte) {
if (nextByte === /* DNL = */ 0xdc && parseDNLMarker) {
offset += 2; // Skip marker length.
const scanLines = view.getUint16(offset);
offset += 2;
if (scanLines > 0 && scanLines !== frame.scanLines) {
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(View on GitHub (pinned to 5903d58d58)
Solutions
- Let pdf.js handle it: DNLMarkerError carries a scanLines field and is caught internally to correct the height — verify you are not unwrapping and rethrowing it as fatal.
- Re-encode the JPEG with a correct SOF height to avoid the DNL marker entirely.
- If you call the jpg decoder directly, pass parseDNLMarker=false to ignore DNL (will instead hit EOI handling).
- Repair the source PDF/image so the JPEG SOF matches the actual line count.
Defensive patterns
Strategy: try-catch
Validate before calling
// External pre-validation of JPEG DNL behavior is impractical; instead validate
// that the JPEG's SOF height is plausible relative to the stream length:
function jpegHeightPlausible(scanLines, byteLength) {
return scanLines > 0 && byteLength > scanLines; // very rough sanity
} Type guard
function isRecoverableDnlError(err) {
return err?.name === 'DNLMarkerError' && typeof err.scanLines === 'number';
} Try / catch
// pdf.js handles DNLMarkerError internally; only relevant if you call the
// decoder directly:
try { decodeScan(...); }
catch (err) {
if (err?.name === 'DNLMarkerError') {
frame.scanLines = err.scanLines; // adopt corrected height
} else throw err;
} Prevention
- Prefer letting pdf.js handle DNLMarkerError; do not rethrow it as fatal.
- Encode JPEGs with a correct SOF height to avoid emitting DNL markers.
- Validate JPEGs with jpegtran before embedding.
When it happens
Trigger: Decoding a JPEG whose scan terminates early and emits a DNL marker declaring a non-zero line count that conflicts with the SOF frame height. Triggered by getDocument rendering of a DCTDecode image, with parseDNLMarker enabled (typically for images whose declared height was deliberately oversized).
Common situations: PDFs that embed JPEGs with a deliberately inflated SOF height and rely on the DNL marker to convey the true height; corrupt JPEGs; the known test cases issue10880/issue10989/issue15492 referenced in the source.
Related errors
- Found EOI marker (0xFFD9) while parsing scan data, possibly
- 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/16886121cbb3628d.
Report an issue: GitHub.