mozilla/pdf.js · error · FormatError
Bad FCHECK in flate stream: ${cmf}, ${flg}
Error message
Bad FCHECK in flate stream: ${cmf}, ${flg} What it means
Thrown by the FlateStream constructor when the FCHECK invariant (((CMF<<8)+FLG) % 31 !== 0) fails. RFC 1950 requires that the 16-bit value formed by CMF and FLG be a multiple of 31 so decoders can detect header corruption. A failure means the two header bytes are inconsistent — either truncated, bit-flipped, or not actually a zlib header. This is the third of four sequential header guards.
Source
Thrown at src/core/flate_stream.js:144
constructor(str, maybeLength) {
super(maybeLength);
this.stream = str;
this.dict = str.dict;
const cmf = str.getByte();
const flg = str.getByte();
if (cmf === -1 || flg === -1) {
throw new FormatError(`Invalid header in flate stream: ${cmf}, ${flg}`);
}
if ((cmf & 0x0f) !== 0x08) {
throw new FormatError(
`Unknown compression method in flate stream: ${cmf}, ${flg}`
);
}
if (((cmf << 8) + flg) % 31 !== 0) {
throw new FormatError(`Bad FCHECK in flate stream: ${cmf}, ${flg}`);
}
if (flg & 0x20) {
throw new FormatError(`FDICT bit set in flate stream: ${cmf}, ${flg}`);
}
this.codeSize = 0;
this.codeBuf = 0;
}
async getImageData(length, _decoderOptions) {
const data = await this.asyncGetBytes();
if (!data) {
return this.getBytes(length);
}
if (data.length <= length) {
return data;
}
return data.subarray(0, length);View on GitHub (pinned to 5903d58d58)
Solutions
- Re-acquire the PDF from a trusted source to rule out bit-rot or transfer corruption.
- Repair with qpdf (which can often decode past minor corruption) or re-export via Ghostscript.
- Catch at the page level and continue rendering other pages; this error is stream-local.
- If authoring, run your zlib output through a decoder round-trip test to verify the header checksum before publishing.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await page.render({ canvasContext, viewport });
} catch (e) {
if (e.name === 'FormatError' && /Bad FCHECK in flate stream/.test(e.message)) {
// zlib header checksum failed — bit-level corruption; re-acquire the PDF
} else throw e;
} Prevention
- Re-acquire PDFs from a trusted source to rule out bit-rot or transfer corruption.
- Repair with qpdf (can often decode past minor corruption) or re-export via Ghostscript.
- Run a round-trip zlib decode test on authored streams before publishing.
When it happens
Trigger: A /FlateDecode stream whose first two bytes are present and the method nibble is 8, but the modulo-31 checksum is wrong — indicating byte-level corruption of the header or a header that merely happens to have CM=8. Fires during FlateStream construction before any actual deflate decoding begins.
Common situations: Bit-level corruption from storage/network errors, PDFs processed by tools that patched bytes incorrectly, or generators with off-by-one header-encoding bugs. Less common than truncation but typical of partially-recovered or repaired PDFs.
Related errors
- Invalid header in flate stream: ${cmf}, ${flg}
- Unknown compression method in flate stream: ${cmf}, ${flg}
- FontFile should be a stream
- FDICT bit set in flate stream: ${cmf}, ${flg}
- Invalid entry in 'Differences' array: ${data}
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/fc09fc2948c3d130.
Report an issue: GitHub.