mozilla/pdf.js · error · FormatError

Descendant fonts are not specified

Error message

Descendant fonts are not specified

What it means

Thrown by preEvaluateFont() when a Type0 (composite) font dictionary has no /DescendantFonts entry. The PDF spec requires Type0 fonts to declare a /DescendantFonts array referencing exactly one CIDFont; without it the font cannot be loaded because the actual glyph data lives in the descendant. This guard precedes the array-index access that would otherwise crash.

Source

Thrown at src/core/evaluator.js:4304

  }

  preEvaluateFont(dict) {
    const baseDict = dict;
    let type = dict.get("Subtype");
    if (!(type instanceof Name)) {
      throw new FormatError("invalid font Subtype");
    }

    let composite = false;
    let hash;
    if (type.name === "Type0") {
      // If font is a composite
      //  - get the descendant font
      //  - set the type according to the descendant font
      //  - get the FontDescriptor from the descendant font
      const df = dict.get("DescendantFonts");
      if (!df) {
        throw new FormatError("Descendant fonts are not specified");
      }
      dict = Array.isArray(df) ? this.xref.fetchIfRef(df[0]) : df;

      if (!(dict instanceof Dict)) {
        throw new FormatError("Descendant font is not a dictionary.");
      }
      type = dict.get("Subtype");
      if (!(type instanceof Name)) {
        throw new FormatError("invalid font Subtype");
      }
      composite = true;
    }

    let firstChar = dict.get("FirstChar");
    if (!Number.isInteger(firstChar)) {
      firstChar = 0;
    }
    let lastChar = dict.get("LastChar");

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Re-save the PDF through Acrobat 'Save As' or Ghostscript to rebuild the Type0 structure.
  2. If authoring, verify your PDF library writes /DescendantFonts as a one-element array of indirect references.
  3. Isolate failing pages with stopAtErrors: true and per-page try/catch.
  4. If the PDF renders in other viewers, report it to PDF.js with the file for fallback-heuristic improvement.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await page.render({ canvasContext, viewport });
} catch (e) {
  if (e.name === 'FormatError' && /Descendant fonts are not specified/.test(e.message)) {
    console.warn('Type0 font missing DescendantFonts, skipping');
  } else throw e;
}

Prevention

When it happens

Trigger: A font dictionary with /Subtype /Type0 whose /DescendantFonts is absent, null, or falsy. Fires during font pre-evaluation for any page that references such a font.

Common situations: PDF generators that build Type0 wrappers incompletely, PDFs that were truncated mid-stream, or font dictionaries damaged by a faulty linearization/optimization pass. Common in PDFs that were machine-modified to embed subsets.

Related errors


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