docling-project/docling · error · ServiceUnavailableError

Service transport request failed after retries.

Error message

Service transport request failed after retries.

What it means

Raised as ServiceUnavailableError when an httpx TransportError (connection failure, timeout, reset) occurs on a retryable HTTP method (GET/HEAD/OPTIONS) and the retry budget (max_retries) is exhausted. The original transport exception is chained via 'from exc' and its string is embedded in the detail. It signals the client could not reach the Docling service at the network/transport layer even after exponential backoff retries.

Source

Thrown at docling/service_client/client.py:636

        return HTTP_RETRY_BACKOFF_BASE_SECONDS * (2**attempt)

    def _transport_retry_delay(
        self,
        *,
        method: str,
        exc: httpx.HTTPError,
        attempt: int,
        max_retries: int,
    ) -> float | None:
        method_name = method.upper()
        if (
            not isinstance(exc, httpx.TransportError)
            or method_name not in TRANSPORT_RETRYABLE_HTTP_METHODS
        ):
            return None
        if attempt < max_retries:
            return self._exponential_backoff_delay(attempt)
        raise ServiceUnavailableError(
            "Service transport request failed after retries.",
            detail=str(exc),
        ) from exc

    def _retry_after_delay_seconds(self, response: httpx.Response) -> float | None:
        retry_after_header = response.headers.get("Retry-After")
        if retry_after_header is None:
            return None

        try:
            return max(0.0, float(retry_after_header))
        except ValueError:
            pass

        try:
            retry_at = parsedate_to_datetime(retry_after_header)
        except (TypeError, ValueError, IndexError, OverflowError):
            return None

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Verify the service is running and reachable: curl the base URL health endpoint (e.g. curl http://localhost:5001/health) from the same machine/container.
  2. Check the base URL configured on DocumentConverter/DoclingServiceClient for typos, wrong port, or wrong scheme.
  3. If a proxy or VPN is required, configure httpx transport/proxy settings or environment variables (HTTP_PROXY/HTTPS_PROXY) in the client environment.
  4. Increase max_retries / backoff settings on the client if the outage is expected to be brief and self-healing.
  5. Wrap calls in a retry loop at the application level with jitter, treating ServiceUnavailableError as transient.

Example fix

// before
result = client.convert("doc.pdf")  # raises ServiceUnavailableError when service is down

# after
from docling.service_client.exceptions import ServiceUnavailableError
import time

for attempt in range(3):
    try:
        result = client.convert("doc.pdf")
        break
    except ServiceUnavailableError:
        if attempt == 2:
            raise
        time.sleep(2 ** attempt)
Defensive patterns

Strategy: retry

Validate before calling

import socket, urlparse

def service_reachable(base_url: str, timeout: float = 2.0) -> bool:
    p = urlparse.urlparse(base_url)
    try:
        with socket.create_connection((p.hostname, p.port or 80), timeout=timeout):
            return True
    except OSError:
        return False

assert service_reachable(client_url) before submitting work

Try / catch

from docling.service_client.exceptions import ServiceUnavailableError

try:
    result = client.convert(src)
except ServiceUnavailableError as exc:
    # transient: detail carries the underlying httpx.TransportError string
    log.warning("transport failure: %s", exc)
    raise RetryableError() from exc

Prevention

When it happens

Trigger: Calling a read/status endpoint such as _poll_task_status or _request_with_retry with method='GET' while the service host is unreachable, DNS fails, the TLS handshake breaks, or the connection times out; the helper retries up to max_retries with _exponential_backoff_delay and, on the final attempt, raises instead of returning a delay.

Common situations: Service URL pointing at a stopped/killed local docling-serve instance, corporate proxy or firewall blocking the host, DNS resolution failures in containers, wrong port after the service moved, or transient network outages longer than the retry window.

Related errors


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