opendataloader-project/opendataloader-pdf · error · ValueError
OCR engine '{ocr_engine}' is not supported in hybrid local m
Error message
OCR engine '{ocr_engine}' is not supported in hybrid local mode (filtered by _OCR_ENGINE_DENYLIST). Available engines: {available} What it means
ValueError raised when the requested ocr_engine is in the module-level _OCR_ENGINE_DENYLIST (currently frozenset({'kserve_v2_ocr'})), which blocks remote-inference-server OCR engines in hybrid local mode for security and reproducibility. This guard is enforced in create_converter too, not just the CLI argparse choices, because programmatic callers bypass argparse. The message lists the engines that remain available (registered kinds minus the denylist).
Source
Thrown at python/opendataloader-pdf/src/opendataloader_pdf/hybrid_server.py:449
TableFormerMode,
TableStructureOptions,
TesseractCliOcrOptions,
TesseractOcrOptions,
)
from docling.document_converter import DocumentConverter, PdfFormatOption
from docling.models.factories import get_ocr_factory
# Delegate engine selection to docling's factory. We block external plugins for
# security/reproducibility; the module-level _OCR_ENGINE_DENYLIST filters
# engines unsuitable for hybrid local mode (e.g., remote inference servers).
ocr_factory = get_ocr_factory(allow_external_plugins=False)
if ocr_engine in _OCR_ENGINE_DENYLIST:
# Programmatic callers (importing this module) bypass argparse `choices`,
# so enforce the denylist here too. Without this, the module-level claim
# that `_OCR_ENGINE_DENYLIST` is shared across CLI and create_converter
# would only be true at the CLI layer.
available = sorted(set(ocr_factory.registered_kind) - _OCR_ENGINE_DENYLIST)
raise ValueError(
f"OCR engine '{ocr_engine}' is not supported in hybrid local mode "
f"(filtered by _OCR_ENGINE_DENYLIST). Available engines: {available}"
)
try:
ocr_options = ocr_factory.create_options(
kind=ocr_engine,
force_full_page_ocr=force_full_page_ocr,
)
except RuntimeError as e:
# Library-friendly error type so programmatic callers can catch and retry
# with a different engine. main() relies on argparse `choices` to gate
# invalid CLI input, so this branch is reached only via direct calls.
available = sorted(set(ocr_factory.registered_kind) - _OCR_ENGINE_DENYLIST)
raise ValueError(
f"Unknown ocr_engine '{ocr_engine}': {e}\nAvailable engines: {available}"
) from e
if ocr_lang:View on GitHub (pinned to a7789b8e77)
Solutions
- Switch to an allowed engine: use one of the values printed in the 'Available engines' list (e.g. easyocr, tesseract, or auto).
- If you genuinely need remote inference, do NOT use hybrid local mode — run the engine as a separate service and adjust your architecture, since the denylist is intentional for local mode.
- Update any persisted config/defaults that reference a denied engine name.
- Check the current denylist via from opendataloader_pdf.hybrid_server import _OCR_ENGINE_DENYLIST before choosing an engine programmatically.
Example fix
# before: denied remote-inference engine in local mode create_converter(ocr_engine='kserve_v2_ocr') # -> ValueError # after: use a locally-available engine create_converter(ocr_engine='easyocr')
Defensive patterns
Strategy: validation
Validate before calling
from opendataloader_pdf.hybrid_server import _OCR_ENGINE_DENYLIST
def is_allowed_engine(engine: str) -> bool:
return engine not in _OCR_ENGINE_DENYLIST
Type guard
def is_denied_engine_error(exc: ValueError) -> bool:
return isinstance(exc, ValueError) and "_OCR_ENGINE_DENYLIST" in str(exc) Try / catch
try:
create_converter(ocr_engine=engine)
except ValueError as e:
if "_OCR_ENGINE_DENYLIST" in str(e):
# pick a locally-available engine instead
engine = "easyocr"
create_converter(ocr_engine=engine)
raise Prevention
- Never hardcode a denied engine name; read _OCR_ENGINE_DENYLIST at runtime.
- Prefer 'auto' or a locally-installed engine (easyocr, tesseract).
- Do not attempt remote-inference engines in hybrid local mode — the denylist is intentional.
When it happens
Trigger: Calling create_converter (or the hybrid server path) with ocr_engine='kserve_v2_ocr' (or any future value added to _OCR_ENGINE_DENYLIST). Programmatic import-and-call bypasses the CLI's argparse choices validation, so this in-function check is what catches it.
Common situations: A caller copies an engine name from docling docs that includes a remote inference server engine blocked here. A config defaults to a denied engine. An upgrade added a new engine to the denylist that the caller's saved config still references.
Related errors
- Unknown ocr_engine '{ocr_engine}': {e}\nAvailable engines: {
- Option --%s: unsupported value '%s'. Supported values: %s, %
- Options --hybrid-hancom-ai-* require --hybrid=hancom-ai (got
- Invalid ocrStrategy: %s (expected off, auto, or force)
- Unsupported hybrid backend: {}
AI-assisted analysis of opendataloader-project/opendataloader-pdf@a7789b8e77 (2026-08-14).
Data as JSON: /api/errors/e9387cfe330bec2a.
Report an issue: GitHub.