docling-project/docling · error · ServiceUnavailableError
{error_message}
Error message
{error_message} What it means
In the sync client's retry handling, _retry_with_exponential_backoff is called for retryable HTTP statuses without a Retry-After header. When attempt >= max_retries it gives up and raises ServiceUnavailableError with the caller-provided error_message (which names the failing operation) plus status code and response detail. It marks definitive exhaustion of the exponential backoff budget.
Source
Thrown at docling/service_client/client.py:594
)
if response.status_code in {429, 503}:
return self._retry_with_retry_after_header(
response=response,
attempt=attempt,
max_retries=max_retries,
)
return response, 0.0
def _retry_with_exponential_backoff(
self,
response: httpx.Response,
attempt: int,
max_retries: int,
error_message: str,
) -> tuple[httpx.Response | None, float]:
if attempt < max_retries:
return None, self._exponential_backoff_delay(attempt)
raise ServiceUnavailableError(
error_message,
status_code=response.status_code,
detail=self._http_error_detail(response),
)
def _retry_with_retry_after_header(
self,
response: httpx.Response,
attempt: int,
max_retries: int,
) -> tuple[httpx.Response | None, float]:
retry_after_delay = self._retry_after_delay_seconds(response)
if retry_after_delay is None:
return response, 0.0
if attempt < max_retries:
return None, retry_after_delay
raise ServiceUnavailableError(
f"Service returned HTTP {response.status_code} after retries.",View on GitHub (pinned to 61d76f1ff3)
Solutions
- Check the service logs for the underlying 5xx cause (often one problematic document).
- Increase http_retries so transient 5xx bursts are absorbed.
- Isolate and retry the failing request separately; skip the poison document in batch runs.
- If errors are deterministic, the document or options may trigger a server bug — report upstream with the detail payload.
Example fix
# before
client = DocumentConverterClient(url) # default retries
for f in files:
client.convert_file(f) # ServiceUnavailableError on server 500s
# after
client = DocumentConverterClient(url, http_retries=5)
for f in files:
try:
client.convert_file(f)
except ServiceUnavailableError as e:
log.error('skipping %s: %s', f, e) Defensive patterns
Strategy: retry
Try / catch
from docling.service_client.exceptions import ServiceUnavailableError
for f in files:
try:
results.append(client.convert_file(f))
except ServiceUnavailableError as e:
log.error('failed %s status=%s detail=%s', f, e.status_code, e.detail)
failed.append(f) # retry later, don't abort the batch Prevention
- Raise http_retries to absorb transient 5xx bursts.
- Log and quarantine poison documents instead of failing the whole batch.
- Check server logs for deterministic 5xx causes.
When it happens
Trigger: Service returning 5xx (e.g. 500/503) on every attempt for operations like file upload or task submission until retries run out; sustained server errors during batch processing; max_retries set low combined with a briefly failing endpoint.
Common situations: docling-serve throwing internal errors on a specific corrupt document; service under heavy load returning 503 for all requests; API rate limiting implemented as plain 503 without Retry-After.
Related errors
- Service request failed after retry loop.
- Service returned HTTP {response.status_code} after retries.
- Service request failed after retry loop.
- Service transport request failed.
- Service transport request failed after retries.
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/f3a4ae1065ffce63.
Report an issue: GitHub.