mozilla/pdf.js · error · JpegError
invalid huffman sequence
Error message
invalid huffman sequence
What it means
Thrown by decodeHuffman() while walking a JPEG Huffman tree bit-by-bit. The loop expects each visited node to be either a number (leaf -> decoded symbol) or an object (branch -> keep traversing). When node becomes undefined (no child for the read bit), typeof falls through the switch and the error fires. This means the entropy-coded bit stream does not match any valid Huffman code path in the loaded table.
Source
Thrown at src/core/jpg.js:206
);
}
// 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;
}
throw new JpegError("invalid huffman sequence");
}
}
function receive(length) {
let n = 0;
while (length > 0) {
n = (n << 1) | readBit();
length--;
}
return n;
}
function receiveAndExtend(length) {
if (length === 1) {
return readBit() === 1 ? 1 : -1;
}
const n = receive(length);
if (n >= 1 << (length - 1)) {View on GitHub (pinned to 5903d58d58)
Solutions
- Re-extract the raw JPEG stream from the PDF and validate it with an external JPEG decoder (e.g. libjpeg, ImageMagick identify) to confirm corruption.
- If the stream is truncated, ensure the PDF object's /Length or stream boundaries are correct and that range-request fetching delivered all bytes.
- Verify the DHT (0xFFC4) markers define complete Huffman tables before the SOS (0xFFDA) scan references them.
- If the image is non-critical, catch JpegError and render a placeholder instead of failing the whole page render.
Example fix
// before
const jpegImg = new JpegImage();
jpegImg.parse(data);
const pixels = jpegImg.getData({ width, height });
// after — guard decode so one bad image doesn't kill page rendering
try {
const jpegImg = new JpegImage();
jpegImg.parse(data);
pixels = jpegImg.getData({ width, height });
} catch (e) {
if (e.name === 'JpegError') {
pixels = null;
}
throw e;
} Defensive patterns
Strategy: try-catch
Try / catch
try {
jpegImg.parse(data);
pixels = jpegImg.getData({ width, height });
} catch (e) {
if (e.name === 'JpegError') { pixels = null; }
throw e;
} Prevention
- Validate embedded JPEG streams with an external decoder before relying on PDF.js for untrusted PDFs.
- Ensure PDF stream extraction preserves exact byte boundaries (correct /Length, full range fetch).
- Isolate image decoding from page rendering so one corrupt image doesn't abort the whole render.
When it happens
Trigger: Reached during baseline/progressive JPEG scan decoding (decodeBaseline, decodeDCFirst, decodeACSuccessive, etc.) when a Huffman table (huffmanTableDC/huffmanTableAC) is malformed or the scan bit-stream is corrupted/truncated so the tree walk hits a missing branch. Also fires if the wrong table index was assigned to a component.
Common situations: Truncated JPEG data embedded in a PDF (partial stream), a corrupted DHT marker that built an incomplete tree, or an encoder that emitted bits inconsistent with the declared table. Common with PDFs produced by broken scanner/fax pipelines or with mismatched DHT/SOS component selectors.
Related errors
- invalid ACn encoding
- missing required Quantization Table.
- JpegImage.parse - unknown marker: ${fileMarker.toString(16)}
- JpegImage.parse - no frame data found.
- SOI not found
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/b95b37831906c68f.
Report an issue: GitHub.