ocrmypdf/OCRmyPDF · error · NotImplementedError

NullOcrEngine cannot generate PDFs directly. Use --pdf-rende

Error message

NullOcrEngine cannot generate PDFs directly. Use --pdf-renderer fpdf2 instead of sandwich mode.

What it means

NullOcrEngine is a no-op OCR engine; it can report 'no text found' but its generate_pdf() unconditionally raises NotImplementedError because it cannot render an invisible-text sandwich PDF itself. Sandwich rendering with this engine is a programming/configuration error.

Source

Thrown at src/ocrmypdf/builtin_plugins/null_ocr.py:146

    </div>
</body>
</html>
'''
        output_hocr.write_text(hocr_content, encoding='utf-8')
        output_text.write_text('', encoding='utf-8')

    @staticmethod
    def generate_pdf(
        input_file: Path,
        output_pdf: Path,
        output_text: Path,
        options: OcrOptions,
    ) -> None:
        """NullOcrEngine cannot generate PDFs directly.

        Use pdf_renderer='fpdf2' instead of 'sandwich'.
        """
        raise NotImplementedError(
            "NullOcrEngine cannot generate PDFs directly. "
            "Use --pdf-renderer fpdf2 instead of sandwich mode."
        )


@hookimpl
def get_ocr_engine(options):
    """Return NullOcrEngine when --ocr-engine none is selected."""
    if options is not None:
        ocr_engine = getattr(options, 'ocr_engine', 'auto')
        if ocr_engine != 'none':
            return None
    return NullOcrEngine()

View on GitHub (pinned to 5074a0b0e1)

Solutions

  1. Set pdf_renderer='fpdf2' (options.pdf_renderer) so no sandwich page generation is needed.
  2. If you intentionally want no OCR text, verify no plugin resolves to NullOcrEngine for sandwich mode.

Example fix

# before
ocr(in, out, pdf_renderer='sandwich', ...)  # engine = NullOcrEngine
# after
ocr(in, out, pdf_renderer='fpdf2', ...)
Defensive patterns

Strategy: validation

Validate before calling

assert not (engine_is_null and options.pdf_renderer == 'sandwich'), \
    'NullOcrEngine requires pdf_renderer=fpdf2'

Try / catch

try:
    ocr(in, out, pdf_renderer='sandwich')
except NotImplementedError as e:
    if 'NullOcrEngine' in str(e):
        ocr(in, out, pdf_renderer='fpdf2')
    raise

Prevention

When it happens

Trigger: Selecting the null engine (e.g. via --force-ocr alternatives or a plugin routing to NullOcrEngine) while the pdf_renderer is 'sandwich' (hocr).

Common situations: Using the null engine to strip/normalize PDFs while forgetting to set --pdf-renderer fpdf2.

Related errors


AI-assisted analysis of ocrmypdf/OCRmyPDF@5074a0b0e1 (2026-08-27). Data as JSON: /api/errors/fe7d4f98b8e758c3. Report an issue: GitHub.