docusealco/docuseal · error · Pdfium::PdfiumError
Failed to load redacted image
Error message
Failed to load redacted image
What it means
Raised by Pdfium::Page#load_image_jpeg (lib/pdfium.rb:1519) after FPDFImageObj_LoadJpegFileInline returns 0, meaning PDFium refused to embed the supplied JPEG bytes into the existing image object. It occurs during image redaction: redact_image_objects extracts the original bitmap, the caller's block paints blackout pixel rects and re-encodes to JPEG, and load_image_jpeg pushes that JPEG back into the page object. The raise fires when the re-encoded bytes are not a JPEG PDFium can decode inline, or the target object/page handle is no longer valid.
Source
Thrown at lib/pdfium.rb:1519
def load_image_jpeg(object_ptr, jpeg)
get_block = FFI::Function.new(:int, %i[pointer ulong pointer ulong]) do |_param, position, out, size|
out.put_bytes(0, jpeg.byteslice(position, size) || ''.b)
1
end
file_access = Pdfium::FPDF_FILEACCESS.new
file_access[:m_FileLen] = jpeg.bytesize
file_access[:m_GetBlock] = get_block
file_access[:m_Param] = FFI::Pointer::NULL
pages_ptr = FFI::MemoryPointer.new(:pointer, 1)
pages_ptr.write_pointer(@page_ptr)
result = Pdfium.FPDFImageObj_LoadJpegFileInline(pages_ptr, 1, object_ptr, file_access)
raise PdfiumError, 'Failed to load redacted image' if result.zero?
end
def text_objects
return @text_objects if @text_objects
ensure_not_closed!
@text_objects = []
object_count = Pdfium.FPDFPage_CountObjects(page_ptr)
return @text_objects if object_count.zero?
text_page = Pdfium.FPDFText_LoadPage(page_ptr)
if text_page.null?
Pdfium.check_last_error("Failed to load text page #{page_index}")
View on GitHub (pinned to 004a22c1c8)
Solutions
- Verify the value returned by the redaction block is non-empty and starts with JPEG magic bytes (\xFF\xD8) before returning it, so load_image_jpeg is skipped (jpeg falsy) for bad encodes.
- Re-encode the redacted bitmap as a baseline (non-progressive) RGB JPEG in the block passed to redact_image_objects.
- Wrap the redaction call per page in begin/rescue Pdfium::PdfiumError and fall back to drawing opaque rects only (draw_redaction_rects) when inline reload fails.
- Make sure the page handle is not closed or reloaded while the redaction block iterates objects; perform redaction before any flatten/rotate/reload on that page object.
Example fix
# before (block may return garbage/empty encode) page.redact_image_objects(rects) do |bitmap, pixel_rects| RedactEncoder.to_jpeg(bitmap, pixel_rects) end # after (skip reload for undecodable encodes) page.redact_image_objects(rects) do |bitmap, pixel_rects| jpeg = RedactEncoder.to_jpeg(bitmap, pixel_rects) jpeg if jpeg.is_a?(String) && jpeg.bytesize > 4 && jpeg.getbyte(0) == 0xFF && jpeg.getbyte(1) == 0xD8 end
Defensive patterns
Strategy: try-catch
Validate before calling
# Validate the JPEG your redaction block produces before returning it
def redactable_jpeg?(jpeg)
jpeg.is_a?(String) &&
jpeg.bytesize > 4 &&
jpeg.getbyte(0) == 0xFF &&
jpeg.getbyte(1) == 0xD8 &&
jpeg.getbyte(-2) == 0xFF && # rough SOI/EOI sanity
jpeg.getbyte(-1) == 0xD9
end Try / catch
begin
page.redact_image_objects(rects) { |bitmap, pixel_rects| encoder.call(bitmap, pixel_rects) }
rescue Pdfium::PdfiumError => e
Rails.logger.warn("redaction skipped page #{page.page_index}: #{e.message}")
page.draw_redaction_rects(rects) # opaque-rect fallback, content still covered
end Prevention
- Encode redacted bitmaps as baseline RGB JPEG — avoid CMYK and progressive modes.
- Never close, flatten, rotate or reload the page while redact_image_objects is iterating.
- Keep the Pdfium::Document and its source buffer alive until every page operation finishes.
- Run redaction on a single thread per document; PDFium FFI handles are not thread-safe.
When it happens
Trigger: Calling redact_image_objects with a block whose return value is nil-check-passing but undecodable: an empty string, PNG or raw bytes mislabeled as JPEG, CMYK/YCCK or progressive JPEGs that the inline loader rejects, or a truncated encode from a crashed encoder. Also triggered when object_ptr is not a valid FPDF_PAGEOBJ_IMAGE anymore, or when the page was closed/reloaded (via close, flatten, rotate) between extract_image_bitmap and the reload call.
Common situations: Redacting scanned/faxed PDFs whose source images use CMYK JPEG colorspaces; a redaction encoder that silently rescues exceptions and returns '' ; running redaction concurrently with another thread calling reload or close on the same page; libpdfium version changes tightening which JPEGs the inline loader accepts.
Related errors
- Failed to import pages
- Failed to flatten page #{page_index}
- 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/f69213aefc628596.
Report an issue: GitHub.