mozilla/pdf.js · error · FormatError

Invalid entry in 'Differences' array: ${data}

Error message

Invalid entry in 'Differences' array: ${data}

What it means

Thrown while parsing a font's /Encoding /Differences array when an entry is neither a number (used to set the current code index) nor a Name (a glyph name like /A). The PDF spec defines the Differences array as an alternating sequence of integers and name operands; any other type is illegal. The error message interpolates the offending value to aid diagnosis.

Source

Thrown at src/core/evaluator.js:3665

    let encoding;
    if (dict.has("Encoding")) {
      encoding = dict.get("Encoding");
      if (encoding instanceof Dict) {
        baseEncodingName = encoding.get("BaseEncoding");
        baseEncodingName =
          baseEncodingName instanceof Name ? baseEncodingName.name : null;
        // Load the differences between the base and original
        if (encoding.has("Differences")) {
          const diffEncoding = encoding.get("Differences");
          let index = 0;
          for (const entry of diffEncoding) {
            const data = xref.fetchIfRef(entry);
            if (typeof data === "number") {
              index = data;
            } else if (data instanceof Name) {
              differences[index++] = data.name;
            } else {
              throw new FormatError(
                `Invalid entry in 'Differences' array: ${data}`
              );
            }
          }
        }
      } else if (encoding instanceof Name) {
        baseEncodingName = encoding.name;
      } else {
        const msg = "Encoding is not a Name nor a Dict";

        if (!this.options.ignoreErrors) {
          throw new FormatError(msg);
        }
        warn(msg);
      }
      // According to table 114 if the encoding is a named encoding it must be
      // one of these predefined encodings.
      if (

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Repair the PDF: run it through qpdf --check then qpdf --linearize, or Ghostscript (gs -sDEVICE=pdfwrite) to normalize the encoding.
  2. If you generate the PDF, audit your Differences-array writer to emit only integers and /Names.
  3. Wrap font-dependent operations (render, getTextContent) per-page in try/catch and degrade gracefully.
  4. Open in Acrobat; if it warns about the font, the encoding is definitively corrupt and must be repaired at the source.

Example fix

// before
await page.render({ canvasContext, viewport }); // throws on bad Encoding

// after
try {
  await page.render({ canvasContext, viewport });
} catch (e) {
  if (e.name === 'FormatError') {
    console.warn('Font encoding corrupt, rendering text may be incomplete');
  } else throw e;
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await page.render({ canvasContext, viewport });
} catch (e) {
  if (e.name === 'FormatError' && /Invalid entry in 'Differences'/.test(e.message)) {
    console.warn('Font encoding corrupt on this page; text may be wrong');
  } else throw e;
}

Prevention

When it happens

Trigger: A font dictionary whose /Encoding >> /Differences array contains a string, boolean, dictionary, null, or other non-spec type at a position where a code-point integer or glyph Name is expected. Fires during font loading (PartialEvaluator.translateFont) on any page that uses the font.

Common situations: Hand-edited PDFs, buggy font subsetting tools, or PDFs that survived a corrupt linearization. Especially common in documents produced by legacy desktop-publishing pipelines or office-software PDF export plugins with encoding bugs.

Related errors


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