mozilla/pdf.js · error · FormatError

invalid object number in the ObjStm stream: ${num}

Error message

invalid object number in the ObjStm stream: ${num}

What it means

A FormatError raised while parsing the N header pairs of an Object Stream: the value read for an object number is not an integer. The ObjStm body begins with N pairs of (objectNumber, offset); a non-integer here means the stream content is truncated, reordered, or corrupt past the dict. The interpolated value is included in the message.

Source

Thrown at src/core/xref.js:979

      throw new FormatError("bad ObjStm stream");
    }
    const first = stream.dict.get("First");
    const n = stream.dict.get("N");
    if (!Number.isInteger(first) || !Number.isInteger(n)) {
      throw new FormatError("invalid first and n parameters for ObjStm stream");
    }
    let parser = new Parser({
      lexer: new Lexer(stream),
      xref: this,
      allowStreams: true,
    });
    const nums = new Array(n);
    const offsets = new Array(n);
    // read the object numbers to populate cache
    for (let i = 0; i < n; ++i) {
      const num = parser.getObj();
      if (!Number.isInteger(num)) {
        throw new FormatError(
          `invalid object number in the ObjStm stream: ${num}`
        );
      }
      const offset = parser.getObj();
      if (!Number.isInteger(offset)) {
        throw new FormatError(
          `invalid object offset in the ObjStm stream: ${offset}`
        );
      }
      nums[i] = num;

      // The entry in the xref table is the object number followed by the index.
      // So if index (gen number) is not the same as the index (i), we fix it
      // (fixes bug 1978317).
      const entry = this.getEntry(num);
      if (entry?.offset === tableOffset && entry.gen !== i) {
        entry.gen = i;
      }

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Re-download the complete file (truncation is the most common cause).
  2. Repair with qpdf or mutool to rebuild object streams.
  3. Catch FormatError at the page/object boundary and skip affected content.
  4. If you control transport, verify Content-Length matches before handoff.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const page = await doc.getPage(n);
} catch (e) {
  if (e instanceof pdfjsLib.FormatError) {
    // log and skip; the ObjStm content is corrupt
  }
}

Prevention

When it happens

Trigger: ObjStm content stream is truncated mid-header; encryption/decryption misalignment shifted tokens; a FlateDecode error produced garbage; offsets written by a buggy writer.

Common situations: Partially downloaded files where the ObjStm stream is cut off; corrupt deflate streams; PDFs from non-conformant generators.

Related errors


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