mozilla/pdf.js · error · FormatError

invalid font Subtype

Error message

invalid font Subtype

What it means

Thrown by preEvaluateFont() when a font dictionary's /Subtype entry is not a PDF Name object. /Subtype distinguishes font kinds (TrueType, Type1, Type0/CIDFontType0/2, Type3, etc.) and must always be a Name; without it the evaluator cannot route the font through the correct loader. This is the top-level guard before any font-type-specific dispatch.

Source

Thrown at src/core/evaluator.js:4292

    const encoding = properties.defaultEncoding;
    for (let charCode = 0; charCode < 256; charCode++) {
      if (charCode in differences && widthsByGlyphName[differences[charCode]]) {
        widths[charCode] = widthsByGlyphName[differences[charCode]];
        continue;
      }
      if (charCode in encoding && widthsByGlyphName[encoding[charCode]]) {
        widths[charCode] = widthsByGlyphName[encoding[charCode]];
        continue;
      }
    }
    return widths;
  }

  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.");
      }

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Repair the PDF with qpdf --linearize or Ghostscript to rebuild font dictionaries.
  2. If you produce PDFs, ensure /Subtype is written as a Name (e.g. /TrueType not "TrueType").
  3. Use stopAtErrors: true only if you need isolation; otherwise let ignoreErrors handle it and accept degraded rendering.
  4. File a PDF.js bug if the PDF renders cleanly in Acrobat — defensive fallbacks may be worth adding.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await page.render({ canvasContext, viewport });
} catch (e) {
  if (e.name === 'FormatError' && /invalid font Subtype/.test(e.message)) {
    // font has no valid Subtype — render with fallback
  } else throw e;
}

Prevention

When it happens

Trigger: Any font dictionary (top-level Font or a Type0 descendant) whose /Subtype is missing, null, a string, or any non-Name type. Fires during preEvaluateFont() which is called from the font-loading path on every font referenced by a page.

Common situations: Truncated or hand-edited PDFs, generators that wrote /Subtype as a literal string instead of a Name, or PDFs damaged by partial download/linearization. Often co-occurs with other font structural errors.

Related errors


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