n8n-io/n8n · error

Failed to parse PDF

Error message

Failed to parse PDF "${attachment.fileName}": ${message}

What it means

pdf-parse (via pdfjs-dist) threw during getText() — the buffer is not a parseable PDF: corrupt xref, truncated download, encryption without credentials, or a non-PDF renamed to .pdf. The message wraps the underlying error; the DOMMatrix polyfill and module load succeeded, so the failure is in the document itself.

Solutions

  1. Verify the file opens in a PDF reader — truncated uploads are the most common cause
  2. Re-export or re-download the PDF and attach again
  3. If the PDF is password-protected, decrypt it before attaching
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at packages/@n8n/instance-ai/src/parsers/pdf-parser.ts:43 when the library encounters an invalid state.

Common situations: See trigger scenarios.

Understand the failure class


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/129e283555711f85. Report an issue: GitHub.

Appendix: source

Thrown at packages/@n8n/instance-ai/src/parsers/pdf-parser.ts:43

	// pdf-parse v2 is backed by pdfjs-dist, which expects a `DOMMatrix` global
	// that Node.js does not provide. Polyfill it before parsing.
	if (typeof Reflect.get(globalThis, 'DOMMatrix') === 'undefined') {
		const { default: DOMMatrix } = await import('@thednp/dommatrix');
		Reflect.set(globalThis, 'DOMMatrix', DOMMatrix);
	}

	const { PDFParse } = await import('pdf-parse');

	const parser = new PDFParse({ data: decoded });
	let extractedText: string;
	let totalPages: number;
	try {
		const result = await parser.getText();
		extractedText = result.text;
		totalPages = result.total;
	} catch (error) {
		const message = error instanceof Error ? error.message : 'unknown error';
		throw new Error(`Failed to parse PDF "${attachment.fileName}": ${message}`);
	} finally {
		await parser.destroy();
	}

	const text = extractedText?.trim() ?? '';
	if (!text) {
		throw new Error(
			`PDF "${attachment.fileName}" contains no extractable text (it may be a scanned image).`,
		);
	}

	if (text.length > MAX_RESULT_CHARS) {
		return {
			text: text.slice(0, MAX_RESULT_CHARS),
			pages: totalPages,
			truncated: true,
		};
	}

View on GitHub (pinned to 5ac6606e81)