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
- Verify the source file size > 0 before calling getDocument (HEAD request, fs.stat, or blob.size).
- Check the fetch response: if (!response.ok || response.headers.get('content-length') === '0') abort early.
- 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
- Check Content-Length / arrayBuffer.byteLength before calling getDocument.
- Handle fetch failures and 200-with-empty-body cases explicitly.
- For uploads, validate file.size > 0 on the client before submission.
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
- BinaryCMapReader.process: Invalid dataSize.
- Page count in top-level pages dictionary is not an integer.
- Invalid type in PageLabel dictionary.
- Invalid style in PageLabel dictionary.
- Invalid prefix in PageLabel dictionary.
AI-assisted analysis of mozilla/pdf.js@5903d58d58 (2026-08-13).
Data as JSON: /api/errors/0e1dafd922d98d25.
Report an issue: GitHub.