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 = nil

View on GitHub (pinned to 004a22c1c8)

Solutions

  1. Retry once with flag = Pdfium::FLAT_PRINT (print appearances) instead of the default FLAT_NORMALDISPLAY.
  2. 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.
  3. Load the document with its password / full permissions before flattening; encrypted docs cannot be edited.
  4. 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

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


AI-assisted analysis of docusealco/docuseal@004a22c1c8 (2026-08-21). Data as JSON: /api/errors/610e63e1b775a614. Report an issue: GitHub.