{"record":{"id":"c6757b08031de4e5","repo":"docusealco/docuseal","slug":"failed-to-load-document-from-memory-pointer-is-nu","errorCode":null,"errorMessage":"Failed to load document from memory, pointer is NULL.","messagePattern":"Failed to load document from memory, pointer is NULL\\.","errorType":"exception","errorClass":"Pdfium::PdfiumError","httpStatus":null,"severity":"error","filePath":"lib/pdfium.rb","lineNumber":629,"sourceCode":"      return doc unless block_given?\n\n      begin\n        yield doc\n      ensure\n        doc.close\n      end\n    end\n\n    def self.open_bytes(bytes, password = nil)\n      buffer = FFI::MemoryPointer.new(:char, bytes.bytesize)\n      buffer.put_bytes(0, bytes)\n\n      doc_ptr = Pdfium.FPDF_LoadMemDocument(buffer, bytes.bytesize, password)\n\n      if doc_ptr.null?\n        Pdfium.check_last_error('Failed to load document from memory')\n\n        raise PdfiumError, 'Failed to load document from memory, pointer is NULL.'\n      end\n\n      doc = new(doc_ptr, buffer)\n\n      return doc unless block_given?\n\n      begin\n        yield doc\n      ensure\n        doc.close\n      end\n    end\n\n    def self.open_io(io, password = nil, &)\n      path = io.path if io.respond_to?(:path)\n\n      if path\n        io.flush","sourceCodeStart":611,"sourceCodeEnd":647,"githubUrl":"https://github.com/docusealco/docuseal/blob/004a22c1c88109c7ba0b567df011a8cb13894001/lib/pdfium.rb#L611-L647","documentation":"Raised by Pdfium::Document.open_bytes when FPDF_LoadMemDocument returns NULL for the in-memory buffer copied into an FFI::MemoryPointer via bytes.bytesize/put_bytes. check_last_error runs first and raises the richer error-code variant (PasswordError for FPDF_ERR_PASSWORD) when PDFium recorded a code, so this plain message typically means empty or truncated bytes, or data that is not a PDF. A non-String argument fails earlier with NoMethodError on bytesize.","triggerScenarios":"Passing '' or header-only bytes from a truncated download; passing base64 text that was never decoded; a String read from an IO without binmode; an encrypted document with a missing password (raises the PasswordError variant instead).","commonSituations":"Handling multipart uploads or object-storage GETs that returned partial content; decoding email attachments; test fixtures with wrong encodings; passing already-decoded JSON fields.","solutions":["Guard for empty input and verify bytes.start_with?('%PDF') before loading","Force binary encoding on the string: bytes.force_encoding(Encoding::BINARY) before open_bytes","If the source is a file or IO, prefer open_file/open_io which handle encoding and streaming","Rescue Pdfium::PasswordError and retry with the password for encrypted documents"],"exampleFix":"# before\ndoc = Pdfium::Document.open_bytes(data)\n\n# after\nraise ArgumentError, 'not a PDF' unless data.is_a?(String) && data.bytesize.positive? && data.start_with?('%PDF')\n\ndoc = Pdfium::Document.open_bytes(data.b)","handlingStrategy":"validation","validationCode":"def loadable_pdf_bytes?(bytes)\n  bytes.is_a?(String) && bytes.bytesize.positive? && bytes.start_with?('%PDF')\nend\n\nraise ArgumentError, 'not a PDF' unless loadable_pdf_bytes?(bytes)\nbytes = bytes.b","typeGuard":null,"tryCatchPattern":"begin\n  Pdfium::Document.open_bytes(bytes, password)\nrescue Pdfium::PasswordError\n  retry_with_password\nrescue Pdfium::PdfiumError => e\n  reject_payload(e.message)\nend","preventionTips":["Freeze a convention: every byte payload passed to open_bytes is forced to Encoding::BINARY at the boundary","Verify downloads completed (Content-Length match) before parsing","Prefer open_bytes over open_file for untrusted input so you validate the exact bytes you parsed"],"tags":["pdfium","in-memory","invalid-pdf","ffi","ruby"],"backgroundTag":"invalid-pdf-file","analyzedSha":"004a22c1c88109c7ba0b567df011a8cb13894001","analyzedAt":"2026-08-21T13:38:23.343Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}