docusealco/docuseal · error · Pdfium::PdfiumError
Failed to flatten page #{page_index}
Error message
Failed to flatten page #{page_index} What it means
Raised by Pdfium::Page#flatten (lib/pdfium.rb:1793) when FPDFPage_Flatten returns FLATTEN_FAIL (0). Flattening bakes annotations and form-field appearances into the page content stream; PDFium refuses when the page's annotation or widget tree is malformed, or the document is otherwise uneditable. Pdfium.check_last_error runs first, so if PDFium recorded a reason it raises the richer message; this generic raise covers the case where the failure left no error code.
Source
Thrown at lib/pdfium.rb:1793
l_ptr, b_ptr, r_ptr, t_ptr = Array.new(4) { FFI::MemoryPointer.new(:float) }
left, bottom, right, top = box.map(&:to_f)
if Pdfium.FPDFPage_GetMediaBox(page_ptr, l_ptr, b_ptr, r_ptr, t_ptr).zero?
Pdfium.FPDFPage_SetMediaBox(page_ptr, left, bottom, right, top)
end
if Pdfium.FPDFPage_GetCropBox(page_ptr, l_ptr, b_ptr, r_ptr, t_ptr).zero?
Pdfium.FPDFPage_SetCropBox(page_ptr, left, bottom, right, top)
end
result = Pdfium.FPDFPage_Flatten(page_ptr, flag)
if result == Pdfium::FLATTEN_FAIL
Pdfium.check_last_error("Failed to flatten page #{page_index}")
raise PdfiumError, "Failed to flatten page #{page_index}"
end
reload if result == Pdfium::FLATTEN_SUCCESS
result
end
def reload
close_page_view
Pdfium.FPDF_ClosePage(@page_ptr)
@page_ptr = Pdfium.FPDF_LoadPage(@document.document_ptr, @page_index)
raise PdfiumError, "Failed to reload page #{page_index}" if @page_ptr.null?
@page_view = false
@rotation = nil
@width = nilView on GitHub (pinned to 004a22c1c8)
Solutions
- Retry once with flag = Pdfium::FLAT_PRINT (print appearances) instead of the default FLAT_NORMALDISPLAY.
- Re-save or repair the source PDF (e.g. re-render it through a clean save) before flattening; broken annotation dictionaries are the most common cause.
- Load the document with its password / full permissions before flattening; encrypted docs cannot be edited.
- Rescue Pdfium::PdfiumError per page and ship the un-flattened page rather than failing the whole document download.
Example fix
# before page.flatten # after begin page.flatten(Pdfium::FLAT_NORMALDISPLAY) rescue Pdfium::PdfiumError page.flatten(Pdfium::FLAT_PRINT) end
Defensive patterns
Strategy: try-catch
Try / catch
begin
page.flatten(Pdfium::FLAT_NORMALDISPLAY)
rescue Pdfium::PdfiumError
begin
page.reload rescue Pdfium::PdfiumError # page may be poisoned after failed flatten
page.flatten(Pdfium::FLAT_PRINT)
rescue Pdfium::PdfiumError => e
Rails.logger.warn("flatten skipped page #{page.page_index}: #{e.message}")
end
end Prevention
- Open password-protected PDFs with credentials before flattening.
- Repair/re-save third-party PDFs whose annotation widgets lack appearance streams.
- Flatten each page independently so one bad page cannot abort the whole document.
- Do not call flatten on a closed page; ensure_not_closed! guards it but keep lifecycles explicit.
When it happens
Trigger: Calling flatten on a page containing broken annotation appearance streams or widget XObjects; flattening an encrypted / permissions-restricted document opened without full access; calling flatten on a page whose handle was closed; flag set to FLAT_NORMALDISPLAY on pages whose annotations only carry print appearances.
Common situations: Signing/completion pipelines that flatten before download; templates built from third-party PDF editors (dragged-in widgets with missing /AP dicts); owner-password-locked PDFs uploaded as templates; running flatten twice or after rotate triggered a reload on a shared page handle.
Related errors
- Failed to import pages
- Failed to load redacted image
- Failed to reload page #{page_index}
- Failed to create new document
- Failed to load document from file '#{file_path}', pointer is
AI-assisted analysis of docusealco/docuseal@004a22c1c8 (2026-08-21).
Data as JSON: /api/errors/610e63e1b775a614.
Report an issue: GitHub.