Selfhost - Modern PDF attachments silently fail to embed due to missing PdfParse module
#12,004 opened on 2026年6月3日
Repository metrics
- Stars
- (9,732 stars)
- PR merge metrics
- (平均マージ 8d 15h) (30d で 21 merged PRs)
説明
Bug description
When attaching a modern PDF (version 1.5+) to an invoice in the self-hosted version, the PDF silently fails to embed in the generated invoice PDF, even if "Embed Images/Documents" is enabled.
This occurs because FPDI natively throws a PdfParserException when encountering PDFs > v1.4. In the App\Services\PdfMaker\PdfMerge class, the exception is caught, and the code attempts to downgrade the PDF by calling \Modules\Admin\Services\PdfParse::downgrade($file). However, this module class is not present in the self-hosted version, causing the class_exists() check to fail. As a result, the document embedding is completely skipped without any error logs.
Steps to reproduce
- Enable "Include attached images/pdfs in the invoice" in Settings -> Invoice Design.
- Attach a PDF saved in format > 1.4 (e.g., a standard export from modern tools like Chrome or Word) to an invoice.
- Click "View PDF" or send the invoice.
- The attached PDF is completely omitted from the final document, and no error is thrown in
laravel.log.
Expected behavior
The application should either natively attempt to downgrade the PDF using Ghostscript (gs) via a fallback if the premium module is missing, or at least log an error explaining why the attachment was skipped.
Environment
- Invoice Ninja v5 (Self-hosted docker
invoiceninja-debian:latest)
Code context
In app/Services/PdfMaker/PdfMerge.php:
} catch (\setasign\Fpdi\PdfParser\PdfParserException $e) {
// If FPDI fails, try downgrading the PDF
if (class_exists(\Modules\Admin\Services\PdfParse::class)) {
$downgradedPdf = \Modules\Admin\Services\PdfParse::downgrade($file);
$pageCount = $pdf->setSourceFile(StreamReader::createByString($downgradedPdf));
}
}
If gs is installed on the host, a simple shell_exec fallback could be implemented here for self-hosted users.