mozilla/pdf.js · error · FormatError

Bad uncompressed block length in flate stream

Error message

Bad uncompressed block length in flate stream

What it means

Thrown during processing of a stored (uncompressed, BTYPE=00) DEFLATE block when the LEN field and its one's-complement NLEN check field are inconsistent. Per RFC 1951, a stored block carries LEN followed by ~LEN as an integrity check; this error means that check failed (with a special exception for empty blocks, per issue 1277).

Source

Thrown at src/core/flate_stream.js:328

      let blockLen = b;
      if ((b = str.getByte()) === -1) {
        this.#endsStreamOnError("Bad block header in flate stream");
        return;
      }
      blockLen |= b << 8;
      if ((b = str.getByte()) === -1) {
        this.#endsStreamOnError("Bad block header in flate stream");
        return;
      }
      let check = b;
      if ((b = str.getByte()) === -1) {
        this.#endsStreamOnError("Bad block header in flate stream");
        return;
      }
      check |= b << 8;
      if (check !== (~blockLen & 0xffff) && (blockLen !== 0 || check !== 0)) {
        // Ignoring error for bad "empty" block (see issue 1277)
        throw new FormatError("Bad uncompressed block length in flate stream");
      }

      this.codeBuf = 0;
      this.codeSize = 0;

      const bufferLength = this.bufferLength,
        end = bufferLength + blockLen;
      buffer = this.ensureBuffer(end);
      this.bufferLength = end;

      if (blockLen === 0) {
        if (str.peekByte() === -1) {
          this.eof = true;
        }
      } else {
        const block = str.getBytes(blockLen);
        buffer.set(block, bufferLength);
        if (block.length < blockLen) {

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Re-export the PDF with a reputable tool (qpdf, Ghostscript, Acrobat) to rebuild all streams.
  2. Validate with qpdf --check to identify the damaged object.
  3. If you are the PDF producer, ensure stored DEFLATE blocks correctly write LEN followed by (~LEN & 0xFFFF).
  4. Fall back to rendering the page without the affected stream content.

Example fix

// before — manual stored-block write with wrong complement
out.writeUInt16LE(len, 0);
out.writeUInt16LE(len, 2); // bug: should be ~len

// after — correct NLEN per RFC 1951
out.writeUInt16LE(len, 0);
out.writeUInt16LE((~len) & 0xffff, 2);
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate DEFLATE stored blocks server-side before embedding
const zlib = require('zlib');
function validateDeflate(buf) {
  try { zlib.inflateSync(buf); return { ok: true }; }
  catch (e) { return { ok: false, error: e.message }; }
}

Try / catch

try {
  await renderTask.promise;
} catch (err) {
  if (err.message?.includes('Bad uncompressed block length in flate stream')) {
    console.warn('Corrupt DEFLATE stored block; attempting page without affected content.');
  } else { throw err; }
}

Prevention

When it happens

Trigger: readBlock() encounters hdr===0 (stored block), reads 4 bytes for LEN and NLEN, and the condition check !== (~blockLen & 0xffff) && !(blockLen === 0 && check === 0) is true. This happens when the stored block's length fields are corrupt.

Common situations: A PDF producer that emits non-standard stored blocks with incorrect complement values. Byte-level corruption in an otherwise-valid stream. PDFs that were assembled by concatenating fragments with misaligned block boundaries.

Related errors


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