{"record":{"id":"1d8c1ec6bcea0693","repo":"docusealco/docuseal","slug":"failed-to-load-signature-index-pointer-is-null","errorCode":null,"errorMessage":"Failed to load signature #{index}, pointer is NULL.","messagePattern":"Failed to load signature #(.+?), pointer is NULL\\.","errorType":"exception","errorClass":"Pdfium::PdfiumError","httpStatus":null,"severity":"error","filePath":"lib/pdfium.rb","lineNumber":858,"sourceCode":"\n      Pdfium.FPDF_CloseDocument(@document_ptr) unless @document_ptr.null?\n\n      @document_ptr = FFI::Pointer::NULL\n      @source_buffer = nil\n\n      @closed = true\n    end\n  end\n\n  class Signature\n    attr_reader :document, :index, :signature_ptr\n\n    def initialize(document, index)\n      @document = document\n      @index = index\n      @signature_ptr = Pdfium.FPDF_GetSignatureObject(document.document_ptr, index)\n\n      raise PdfiumError, \"Failed to load signature #{index}, pointer is NULL.\" if @signature_ptr.null?\n    end\n\n    def byte_range\n      @byte_range ||=\n        begin\n          count = Pdfium.FPDFSignatureObj_GetByteRange(signature_ptr, nil, 0)\n          buffer = FFI::MemoryPointer.new(:int, count)\n          Pdfium.FPDFSignatureObj_GetByteRange(signature_ptr, buffer, count)\n\n          buffer.read_array_of_int(count)\n        end\n    end\n\n    def signed_end\n      @signed_end ||= byte_range.last(2).sum\n    end\n\n    def contents","sourceCodeStart":840,"sourceCodeEnd":876,"githubUrl":"https://github.com/docusealco/docuseal/blob/004a22c1c88109c7ba0b567df011a8cb13894001/lib/pdfium.rb#L840-L876","documentation":"Raised by Pdfium::Signature.new when FPDF_GetSignatureObject returns NULL for the given index. There is no check_last_error on this path; the near-universal cause is an index at or above the document's signature count (FPDF_GetSignatureCount). Document#signatures only constructs Signature objects for 0...signature_count, so hitting this directly means manual construction with an unchecked index or a count/index mismatch.","triggerScenarios":"Pdfium::Signature.new(doc, 3) on a document with 2 signatures; iterating 0..doc.signature_count inclusively instead of 0...count; counting signatures on one document but constructing Signature objects against another.","commonSituations":"Hand-written signature-verification flows (verify_pdf_signature.rb style) with inclusive range mistakes; caching a count then mutating the document before use.","solutions":["Use doc.signatures instead of constructing Signature manually","Validate index against doc.signature_count before constructing","Re-fetch signature_count after document mutations instead of trusting a cached value"],"exampleFix":"# before\n(0..doc.signature_count).each { |i| use Pdfium::Signature.new(doc, i) } # off-by-one\n\n# after\ndoc.signatures.each { |sig| use sig }","handlingStrategy":"validation","validationCode":"raise ArgumentError, 'no such signature' unless index >= 0 && index < doc.signature_count\nsig = Pdfium::Signature.new(doc, index)","typeGuard":null,"tryCatchPattern":"begin\n  Pdfium::Signature.new(doc, index)\nrescue Pdfium::PdfiumError => e\n  raise unless e.message.include?('Failed to load signature')\n  nil # caller treats as absent signature\nend","preventionTips":["Enumerate via doc.signatures instead of constructing Signature by index","Use exclusive ranges (0...count) when iterating signatures manually","Re-query signature_count after any document mutation"],"tags":["pdfium","signatures","index-validation","ruby"],"backgroundTag":"index-out-of-bounds","analyzedSha":"004a22c1c88109c7ba0b567df011a8cb13894001","analyzedAt":"2026-08-21T13:38:23.343Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}