docling-project/docling · error · NotImplementedError
ThreadedDoclingParseDocumentBackend only supports iter_pages
Error message
ThreadedDoclingParseDocumentBackend only supports iter_pages().
What it means
ThreadedDoclingParseDocumentBackend implements the lazily-threaded PDF parsing strategy where pages are produced as the parser completes them via iter_pages(). Its load_page(page_no) intentionally raises NotImplementedError because random-access page loading is incompatible with the threaded, streaming design. Hitting it is an API contract violation, not an environmental problem.
Source
Thrown at docling/backend/docling_parse_backend.py:555
docling-parse document is loaded purely to read the (cheap, structure-only) outline.
"""
password = (
self.options.password.get_secret_value() if self.options.password else None
)
if isinstance(self.path_or_stream, BytesIO):
self.path_or_stream.seek(0)
dp_doc = DoclingPdfParser(loglevel="fatal").load(
path_or_stream=self.path_or_stream, lazy=True, password=password
)
if dp_doc is None:
return []
try:
return extract_outline_from_docling_parse(dp_doc)
finally:
dp_doc.unload()
def load_page(self, page_no: int) -> PdfPageBackend:
raise NotImplementedError(
"ThreadedDoclingParseDocumentBackend only supports iter_pages()."
)
def iter_pages(self) -> Iterator[ThreadedDoclingParsePageBackend]:
for result in self.parser.iterate_results():
yield ThreadedDoclingParsePageBackend(result)
def unload(self) -> None:
if self._closed:
return
self._closed = True
self.parser.unload(self.doc_key)
super().unload()
View on GitHub (pinned to 61d76f1ff3)
Solutions
- Use iter_pages() to consume pages from the threaded backend instead of load_page().
- If you need random access, switch the pipeline back to the default parse backend (drop the threaded/parse-threads pipeline mode).
- Materialize pages first when both patterns are needed: pages = list(backend.iter_pages()), then index into the list.
- Guard generic helpers with hasattr/use a capability check or isinstance test against the threaded backend before calling load_page.
Example fix
# before page = backend.load_page(3) # NotImplementedError on threaded backend # after pages = list(backend.iter_pages()) page = pages[3] if len(pages) > 3 else None
Defensive patterns
Strategy: validation
Validate before calling
# Feature-detect before random page access:
if hasattr(backend, "load_page") and type(backend).load_page is not object.__getattribute__:
pass # too loose; prefer explicit type check below Type guard
from docling.backend.docling_parse_backend import ThreadedDoclingParseDocumentBackend
def supports_random_page_access(backend) -> bool:
return not isinstance(backend, ThreadedDoclingParseDocumentBackend) Try / catch
try:
page = backend.load_page(n)
except NotImplementedError:
pages = list(backend.iter_pages()) # fallback: materialize streaming pages
page = pages[n] if n < len(pages) else None Prevention
- Write page-consumers against iter_pages() — it works on every backend.
- Type-check for the threaded backend before calling load_page in shared helpers.
- Materialize pages into a list when both streaming and indexed access are needed.
When it happens
Trigger: Calling load_page(n) on ThreadedDoclingParseDocumentBackend — directly in custom code, or through generic code that assumes every AbstractPdfDocumentBackend supports random page access (e.g. OCR utilities or page-render helpers that fetch pages by number).
Common situations: Custom pipelines written against the non-threaded DoclingParseDocumentBackend (where load_page works) later switched to PdfPipelineMode.PARSE_THREADS; shared helper code iterating pages by index; third-party code unaware of the threaded backend's contract.
Related errors
- docling-parse could not load document {self.document_hash}:
- docling-parse could not load document {self.document_hash}.
- Incompatible file format {self.input_format} was passed to a
- pypdfium could not load document with hash {self.document_ha
- Unexpected: {type(self.path_or_stream)=}
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/6f759d92eafd71b7.
Report an issue: GitHub.