mozilla/pdf.js · warning · FormatError

FontFile is empty

Error message

FontFile is empty

What it means

Thrown inside translateFont() when a font descriptor's embedded font stream exists and is a valid BaseStream but contains zero bytes (isEmpty is true). An empty font program cannot be parsed, so PDF.js refuses it. Like error 111, this is inside the ignoreErrors-aware try/catch, so the default render path warns and substitutes a fallback font rather than crashing.

Source

Thrown at src/core/evaluator.js:4629

        fontFile = descriptor.get(n);
        if (fontFile) {
          fontFileN = n;
          break;
        }
      }

      if (fontFile) {
        if (!(fontFile instanceof BaseStream)) {
          throw new FormatError("FontFile should be a stream");
        } else {
          if (fontFile.isAsync) {
            const bytes = await fontFile.asyncGetBytes();
            if (bytes) {
              fontFile = new Stream(bytes, 0, bytes.length, fontFile.dict);
            }
          }
          if (fontFile.isEmpty) {
            throw new FormatError("FontFile is empty");
          }
        }
      }
    } catch (ex) {
      if (!this.options.ignoreErrors) {
        throw ex;
      }
      warn(`translateFont - fetching "${fontName.name}" font file: "${ex}".`);
      fontFile = null;
    }
    let isInternalFont = false;
    let glyphScaleFactors = null;
    let systemFontInfo = null;
    if (fontFile) {
      if (fontFile.dict) {
        const subtypeEntry = fontFile.dict.get("Subtype");
        if (subtypeEntry instanceof Name) {
          subtype = subtypeEntry.name;

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Re-download or re-acquire the PDF from its source to ensure completeness; verify file size matches expectation.
  2. Re-embed the font from the source document via a conformant exporter.
  3. Rely on ignoreErrors (default) to fall back to a standard font — text will render with substituted glyphs.
  4. If authoring, write a unit test that asserts each embedded font stream has non-zero length before publishing the PDF.
Defensive patterns

Strategy: validation

Validate before calling

// Already gated by options.ignoreErrors. To avoid the throw, use default path:
const pdf = await getDocument({ url }).promise;
// Empty font streams will warn and fall back to a standard font.

Prevention

When it happens

Trigger: A /FontFile* stream whose /Length is 0 or whose bytes are exhausted, often because the stream data was truncated or never written despite the stream object existing. Fires during translateFont() after the stream-type check passes.

Common situations: Truncated downloads of PDFs (font stream is at the end and got cut off), faulty PDF optimizers that zeroed stream contents, or generators that wrote a stream header but failed to flush the buffer. Common in PDFs transferred over unstable connections or stored on flaky media.

Related errors


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