docusealco/docuseal · error · Pdfium::PdfiumError
Failed to create bitmap (FPDFBitmap_Create returned NULL)
Error message
Failed to create bitmap (FPDFBitmap_Create returned NULL)
What it means
Raised by Page#render_to_bitmap when FPDFBitmap_Create returns NULL for the computed render dimensions. This is a native allocation failure: the bitmap consumes roughly width*height*4 bytes, so oversized dimensions (large scale values, explicit width/height, or poster-sized pages) exhaust the memory budget. check_last_error runs first with the 'potential pre-existing error' context, but PDFium records no error code for bitmap allocation, so this plain raise is what you see.
Source
Thrown at lib/pdfium.rb:1032
def ensure_not_closed!
raise PdfiumError, 'Page is closed.' if closed?
@document.ensure_not_closed!
end
def render_to_bitmap(width: nil, height: nil, scale: nil, background_color: 0xFFFFFFFF,
flags: FPDF_ANNOT | FPDF_LCD_TEXT | FPDF_NO_NATIVETEXT | FPDF_REVERSE_BYTE_ORDER)
ensure_not_closed!
render_width, render_height = calculate_render_dimensions(width, height, scale)
bitmap_ptr = Pdfium.FPDFBitmap_Create(render_width, render_height, 1)
if bitmap_ptr.null?
Pdfium.check_last_error('Failed to create bitmap (potential pre-existing error)')
raise PdfiumError, 'Failed to create bitmap (FPDFBitmap_Create returned NULL)'
end
Pdfium.FPDFBitmap_FillRect(bitmap_ptr, 0, 0, render_width, render_height, background_color)
Pdfium.FPDF_RenderPageBitmap(bitmap_ptr, page_ptr, 0, 0, render_width, render_height, 0, flags)
unless form_handle.null?
Pdfium.FPDF_FFLDraw(form_handle, bitmap_ptr, page_ptr, 0, 0, render_width, render_height, 0, flags)
end
buffer_ptr = Pdfium.FPDFBitmap_GetBuffer(bitmap_ptr)
stride = Pdfium.FPDFBitmap_GetStride(bitmap_ptr)
bitmap_data = buffer_ptr.read_bytes(stride * render_height)
[bitmap_data, render_width, render_height]
ensure
Pdfium.FPDFBitmap_Destroy(bitmap_ptr) if bitmap_ptr && !bitmap_ptr.null?View on GitHub (pinned to 004a22c1c8)
Solutions
- Cap render dimensions: pass explicit width/height clamped to roughly 3000-5000px instead of an unbounded scale
- Compute the target pixel count from page.width/height first and skip or downscale when it exceeds a budget
- Free other documents and bitmaps before large renders; raise the container memory limit
- Add Pdfium::FPDF_RENDER_LIMITEDIMAGECACHE to the flags to bound pdfium's image cache
Example fix
# before bitmap = page.render_to_bitmap(scale: 8) # after MAX = 3000 scale = [8, (MAX / page.width).to_f, (MAX / page.height).to_f].min bitmap = page.render_to_bitmap(scale: scale)
Defensive patterns
Strategy: validation
Validate before calling
MAX_SIDE = 3000 MAX_PIXELS = 8_000_000 def clamped_scale(page, desired) s = [(desired || 1).to_f, 0.1].max s = [s, MAX_SIDE / page.width, MAX_SIDE / page.height].min s = [s, Math.sqrt(MAX_PIXELS / (page.width * page.height))].min [s, 0.1].max end
Try / catch
begin
page.render_to_bitmap(scale: scale)
rescue Pdfium::PdfiumError => e
raise unless e.message.include?('Failed to create bitmap')
page.render_to_bitmap(width: 1500, height: nil) # degrade gracefully
end Prevention
- Never pass user-supplied width/height/scale unchecked into render_to_bitmap
- Budget pixels: width*height*4 bytes of native memory per render
- Add FPDF_RENDER_LIMITEDIMAGECACHE to render flags for cache bounding
When it happens
Trigger: render_to_bitmap(scale: 8) on a large page; passing width: 20000 explicitly; rendering A0/architecture drawings at default scale; rendering while the process is already near its memory cap.
Common situations: High-DPI thumbnail generation; zoomed-view rendering features; unvalidated user-supplied render dimensions (a denial-of-service vector); low container memory limits.
Related errors
- Failed to create new document
- Failed to load document from file '#{file_path}', pointer is
- Failed to load document from memory, pointer is NULL.
- Failed to load document from IO, pointer is NULL.
- Document is closed.
AI-assisted analysis of docusealco/docuseal@004a22c1c8 (2026-08-21).
Data as JSON: /api/errors/44883d81eda1f0d4.
Report an issue: GitHub.