docling-project/docling · error · RuntimeError

OpenDocument backend could not load document with hash {docu

Error message

OpenDocument backend could not load document with hash {document_hash}

What it means

RuntimeError raised by _load_odf_document when the odfdo OdfDocument constructor fails on either a BytesIO or a path input. It is the OpenDocument backend's equivalent of the docx DocumentLoadError, wrapping the original exception with the document hash for traceability.

Source

Thrown at docling/backend/opendocument_backend.py:143

    except ValidationError:
        if _ODF_HREF_SCHEME_RE.match(href):
            # Looks like an attempted absolute URL (has a scheme) that failed
            # to parse, e.g. a malformed host. Don't guess by treating it as
            # a filesystem path.
            return None
        return Path(href)


def _load_odf_document(
    path_or_stream: BytesIO | Path, document_hash: str
) -> OdfDocument:
    """Load an ODF document from a path or in-memory stream."""
    try:
        if isinstance(path_or_stream, BytesIO):
            return OdfDocument(path_or_stream)
        return OdfDocument(str(path_or_stream))
    except Exception as e:
        raise RuntimeError(
            f"OpenDocument backend could not load document with hash {document_hash}"
        ) from e


class _OdfBaseBackend(DeclarativeDocumentBackend):
    """Shared loading / validation logic for ODT, ODS and ODP backends."""

    _odf_type: str = ""  # "text", "spreadsheet" or "presentation"

    @override
    def __init__(
        self,
        in_doc: InputDocument,
        path_or_stream: BytesIO | Path,
        options: OdsBackendOptions | None = None,
    ) -> None:
        if not _ODFDO_AVAILABLE:
            raise ImportError(_INSTALL_HINT) from _ODFDO_IMPORT_ERROR

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Verify the file with: unzip -l file.odt — a valid ODF file lists content.xml and META-INF/manifest.xml.
  2. Re-save the document from LibreOffice in ODF format (and without encryption) and retry.
  3. If the input is actually another format, detect it (python-magic) and route to the correct backend.
  4. Catch the RuntimeError at ingest and quarantine the file.

Example fix

# before
backend = OdtDocumentBackend(in_doc, path)  # RuntimeError: could not load

# after
try:
    backend = OdtDocumentBackend(in_doc, path)
except RuntimeError as e:
    logger.error('ODF load failed for %s', path)
    backend = None
Defensive patterns

Strategy: try-catch

Validate before calling

import zipfile
with zipfile.ZipFile(path) as z:
    names = z.namelist()
if 'content.xml' not in names or 'META-INF/manifest.xml' not in names:
    raise ValueError('not a valid ODF package')

Try / catch

try:
    backend = OdtDocumentBackend(in_doc, path)
except RuntimeError as e:
    logger.error('ODF load failed (%s): %s', path, e)
    quarantine(path)

Prevention

When it happens

Trigger: Constructing an ODT/ODS/ODP backend with a file that odfdo cannot parse: not a ZIP-based ODF package, a password-protected ODF file, or a corrupted archive.

Common situations: Office exports saved in older binary formats (.sdw, .sxc) or .doc renamed to .odt; encrypted LibreOffice documents; partial uploads.

Related errors


AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14). Data as JSON: /api/errors/e7bbcd86720de075. Report an issue: GitHub.