docusealco/docuseal · error · Pdfium::PdfiumError
Failed to reload page #{page_index}
Error message
Failed to reload page #{page_index} What it means
Raised by Pdfium::Page#reload (lib/pdfium.rb:1807) when FPDF_LoadPage returns NULL after the old page handle was already closed with FPDF_ClosePage. reload is called internally after successful flatten and rotate, so this error means the page became unopenable mid-operation: the parent document handle is closed/freed, the in-memory document was corrupted by the preceding mutation, or the page index no longer resolves. Because the old handle is already destroyed, the page object is unusable after this raise.
Source
Thrown at lib/pdfium.rb:1807
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
@height = nil
@box = nil
@document.reset_annot_count(@page_index)
reset_memoization
end
def close
return if closed?
unless @page_ptr.null?
close_page_view
View on GitHub (pinned to 004a22c1c8)
Solutions
- Process a document (and its pages) from a single thread; never share Pdfium::Document/Page handles across threads.
- Rescue PdfiumError from flatten/rotate, then rebuild from scratch: close the document, re-load it from the original bytes, and return the fresh page instead of the poisoned one.
- Keep a reference to the source buffer for the whole document lifetime so the in-memory document stays valid through reload.
- If it reproduces on one specific file, extract that page into a standalone PDF and re-run to isolate a corrupt page tree.
Example fix
# before page.flatten page.text_objects # after begin page.flatten rescue Pdfium::PdfiumError doc = Pdfium.open_document(original_bytes) page = doc.page(page.index) # fresh handles after failed reload end page.text_objects
Defensive patterns
Strategy: fallback
Validate before calling
# Before mutating (flatten/rotate), confirm the document handle is still open raise ArgumentError, 'document closed' if document.closed?
Try / catch
begin page.flatten # may internally reload rescue Pdfium::PdfiumError # old page handle is destroyed after a failed reload — rebuild from source document.close document = Pdfium.open(original_bytes) page = document.page(index) end
Prevention
- One thread per document; never share Document/Page handles across threads.
- Retain the original PDF bytes so any page can be rebuilt after a failed reload.
- Treat a failed reload as poisoning the whole in-memory document — reopen rather than retry the page.
- Guard mutating sequences (rotate -> flatten) with a single ownership context.
When it happens
Trigger: reload triggered by a successful flatten/rotate while another thread called close on the document or page (concurrent access to the FFI handle); in-memory PDF buffer freed (source_buffer garbage collected on the Document) before reload; document dictionary damaged by the transform so FPDF_LoadPage rejects the page; @page_index out of range after document mutation.
Common situations: Multi-threaded PDF processing where pages of one document are shared across threads (PDFium handles are not thread-safe); long-running jobs that flatten many pages while a watchdog closes the document on timeout; rare PDFs whose page tree breaks after TransFormWithClip.
Related errors
- Failed to import pages
- Failed to load redacted image
- Failed to flatten 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/4f375d5176d3625c.
Report an issue: GitHub.