docling-project/docling · error · TaskNotFoundError

Task {task_id} was not found.

Error message

Task {task_id} was not found.

What it means

While polling task status via GET /v1/status/poll/{task_id}, the service returned HTTP 404, meaning no task with that identifier exists (anymore). The async client translates this into TaskNotFoundError. Common causes are an expired/completed-and-evicted task, a wrong task_id, or querying a different service instance that never held the task.

Source

Thrown at docling/service_client/_async_client.py:856

                path=f"/v1/chunk/{chunker.value}/file/async",
                data=self._form_encode_options(data),
                files=files,
            )

        if response.status_code != 200:
            self._raise_for_generic_http_error(
                response, "Chunk task submission failed."
            )
        return TaskStatusResponse.model_validate_json(response.text)

    async def _poll_task_status(self, task_id: str, wait: float) -> TaskStatusResponse:
        response = await self._request_with_retry(
            method="GET",
            path=f"/v1/status/poll/{task_id}",
            params={"wait": wait},
        )
        if response.status_code == 404:
            raise TaskNotFoundError(f"Task {task_id} was not found.")
        if response.status_code != 200:
            self._raise_for_generic_http_error(
                response, f"Polling task {task_id} failed."
            )
        return TaskStatusResponse.model_validate_json(response.text)

    async def _poll_task_status_using_client(
        self,
        task_id: str,
        wait: float,
        async_client: httpx.AsyncClient,
    ) -> TaskStatusResponse:
        response = await self._request_with_retry_using_client(
            async_client=async_client,
            method="GET",
            path=f"/v1/status/poll/{task_id}",
            params={"wait": wait},
        )

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Poll promptly after submitting and keep the polling session within the service's task retention window.
  2. Ensure sticky routing or a shared task backend when running multiple service replicas.
  3. Verify the task_id string matches the one returned at submission.
  4. On TaskNotFoundError, treat the task as lost and resubmit the conversion rather than polling forever.

Example fix

# before
status = await client._poll_task_status(task_id, wait=30.0)  # 404 -> TaskNotFoundError

# after
from docling.service_client.exceptions import TaskNotFoundError
try:
    status = await client.wait_for_task(task_id)
except TaskNotFoundError:
    job = await client.submit(...); task_id = job.task_id  # resubmit
Defensive patterns

Strategy: try-catch

Try / catch

from docling.service_client.exceptions import TaskNotFoundError

try:
    status = await poll(task_id)
except TaskNotFoundError:
    job = await resubmit(source)  # task evicted/lost; convert again

Prevention

When it happens

Trigger: Polling a task after the service's retention window has evicted it; using a task_id from a previous deployment or another service instance (e.g. after a container restart with in-memory task store); typo'd or truncated task_id; task record removed once terminal results were garbage-collected.

Common situations: Resuming a batch job after a long pause or service restart; multiple replicas behind a load balancer without shared task state; storing task ids in a queue and processing them hours later.

Related errors


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