docling-project/docling · warning · ResultNotReadyError
Result for task {task_id} is not ready.
Error message
Result for task {task_id} is not ready. What it means
Raised as ResultNotReadyError when the result endpoint returns 'Task result not found' but the task is not in a terminal state — the conversion is still running (or its status is unknown). It is the client's signal that the caller asked for a result too early and should wait/poll again rather than treat it as a hard failure.
Source
Thrown at docling/service_client/client.py:674
now = datetime.now(tz=retry_at.tzinfo or timezone.utc)
return max(0.0, (retry_at - now).total_seconds())
def _raise_for_result_404(
self,
task_id: str,
response: httpx.Response,
last_status: TaskStatusResponse | None,
) -> None:
detail = self._http_error_detail(response)
if detail == "Task not found.":
raise TaskNotFoundError(f"Task {task_id} was not found.")
if detail is not None and detail.startswith("Task result not found"):
if last_status is not None and is_terminal_task_status(last_status):
if last_status.task_status == "failure":
message = last_status.error_message or f"Task {task_id} failed."
raise TaskExecutionError(message, failure=last_status.failure)
raise ResultExpiredError(f"Result for task {task_id} has expired.")
raise ResultNotReadyError(f"Result for task {task_id} is not ready.")
raise ServiceError(
"Unexpected result lookup error.",
status_code=response.status_code,
detail=detail,
)
def _raise_if_task_failure_result(self, response: httpx.Response) -> None:
content_type = response.headers.get("content-type", "")
if "json" not in content_type.lower():
return
try:
payload = response.json()
except ValueError:
return
if not isinstance(payload, dict) or payload.get("kind") != "TaskFailureResult":
returnView on GitHub (pinned to 61d76f1ff3)
Solutions
- Catch ResultNotReadyError and loop: wait, re-check task status, then retry result retrieval.
- Increase the timeout/poll wait you pass to job.result(...) so the client waits for terminal status internally.
- Reduce conversion latency with max_num_pages/page_range or smaller files so results appear sooner.
- For many tasks, collect results only after status polling reports terminal states.
Example fix
# before
result = job.result() # raises ResultNotReadyError while task is processing
# after
from docling.service_client.exceptions import ResultNotReadyError
import time
while True:
try:
result = job.result()
break
except ResultNotReadyError:
time.sleep(2)
continue Defensive patterns
Strategy: retry
Try / catch
from docling.service_client.exceptions import ResultNotReadyError
import time
while True:
try:
result = job.result()
break
except ResultNotReadyError:
time.sleep(poll_interval) # still processing; wait and retry Prevention
- Pass an adequate timeout to job.result() so the client waits internally.
- Poll status to terminal before fetching results.
- Keep poll_interval modest (1-5s) and bounded by an overall deadline.
- Reduce document size to shorten processing time.
When it happens
Trigger: Fetching /v1/result/{task_id} (e.g. via an impatient result() call or race between status polling and result fetch) while the task is still queued or processing; last_status is None or non-terminal, so the 404 'Task result not found' maps to 'not ready' instead of expired/failed.
Common situations: Large documents with long processing times, callers skipping the wait/poll phase, concurrency contention slowing the pipeline, or short poll timeouts causing premature result fetches.
Related errors
- Task {task_id} was not found.
- Timed out waiting for task {task_id} after {timeout:.2f}s.
- {last_status.error_message or f"Task {task_id} failed."}
- Result for task {task_id} has expired.
- {task_failure.failure.message}
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/10757060aee6b0c7.
Report an issue: GitHub.