mozilla/pdf.js · error · InvalidPDFException

The PDF file is empty, i.e. its size is zero bytes.

Error message

The PDF file is empty, i.e. its size is zero bytes.

What it means

InvalidPDFException thrown by the PDFDocument constructor when the input stream reports length <= 0. pdf.js refuses to construct a document from an empty stream because there is no PDF data to parse (no header, no xref, no body). This is fatal for that load.

Source

Thrown at src/core/document.js:1024

  #pagePromises = new Map();

  // Map<id, {byteRange: number[4], pkcs7: Uint8Array}> — populated by the
  // `signatures` getter, consumed by `getSignatureData`. We deliberately
  // keep the signed byte spans out of the metadata array and only slice
  // them out of the stream when the viewer actually asks to verify.
  #signatureData = null;

  #version = null;

  constructor(pdfManager, stream) {
    if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
      assert(
        stream instanceof BaseStream,
        'PDFDocument: Invalid "stream" argument.'
      );
    }
    if (stream.length <= 0) {
      throw new InvalidPDFException(
        "The PDF file is empty, i.e. its size is zero bytes."
      );
    }

    this.pdfManager = pdfManager;
    this.stream = stream;
    this.xref = new XRef(stream, pdfManager);

    const idCounters = {
      font: 0,
    };
    this._globalIdFactory = class {
      static getDocId() {
        return `g_${pdfManager.docId}`;
      }

      static createFontId() {
        return `f${++idCounters.font}`;

View on GitHub (pinned to 5903d58d58)

Solutions

  1. Verify the source file size > 0 before calling getDocument (HEAD request, fs.stat, or blob.size).
  2. Check the fetch response: if (!response.ok || response.headers.get('content-length') === '0') abort early.
  3. Map InvalidPDFException to a clear 'file is empty or corrupt' message.

Example fix

// before
const doc = await getDocument({ url }).promise;

// after
const resp = await fetch(url);
if (!resp.ok || Number(resp.headers.get('content-length')) === 0) {
  throw new Error('The file is empty or could not be downloaded.');
}
const buf = await resp.arrayBuffer();
if (buf.byteLength === 0) throw new Error('Downloaded file is empty.');
const doc = await getDocument({ data: buf }).promise;
Defensive patterns

Strategy: validation

Validate before calling

const resp = await fetch(url);
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const len = Number(resp.headers.get('content-length'));
if (len === 0) throw new Error('File is empty (0 bytes).');
const data = await resp.arrayBuffer();
if (data.byteLength === 0) throw new Error('Downloaded file is empty.');

Type guard

function isNonEmptyStreamData(data) {
  return (data instanceof ArrayBuffer && data.byteLength > 0) ||
         (data instanceof Uint8Array && data.length > 0) ||
         (data instanceof Blob && data.size > 0);
}

Try / catch

try {
  const doc = await getDocument({ data }).promise;
} catch (e) {
  if (e.name === 'InvalidPDFException' && /size is zero bytes/.test(e.message)) {
    notifyUser('The file is empty or could not be downloaded.');
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Loading a zero-byte file or URL; an aborted fetch whose response body resolved to an empty ArrayBuffer/Blob; an empty ReadableStream; a server returning 200 with no body.

Common situations: Network race where the response is truncated to zero bytes; misconfigured upload that wrote nothing; pointing getDocument at a non-existent path that returns an empty 200.

Related errors


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