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

  1. 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.
  2. Re-encode the JPEG with a correct SOF height to avoid the DNL marker entirely.
  3. If you call the jpg decoder directly, pass parseDNLMarker=false to ignore DNL (will instead hit EOI handling).
  4. 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

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


AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13). Data as JSON: /api/errors/16886121cbb3628d. Report an issue: GitHub.