{"record":{"id":"c2b567718cd68106","repo":"docling-project/docling","slug":"service-transport-request-failed","errorCode":null,"errorMessage":"Service transport request failed.","messagePattern":"Service transport request failed\\.","errorType":"exception","errorClass":"ServiceUnavailableError","httpStatus":null,"severity":"error","filePath":"docling/service_client/_async_client.py","lineNumber":699,"sourceCode":"                    method=method_name,\n                    url=url,\n                    json=json,\n                    data=data,\n                    files=files,\n                    params=params,\n                    headers=headers,\n                )\n            except httpx.HTTPError as exc:\n                delay = self._transport_retry_delay(\n                    method=method_name,\n                    exc=exc,\n                    attempt=attempt,\n                    max_retries=max_retries,\n                )\n                if delay is not None:\n                    await asyncio.sleep(delay)\n                    continue\n                raise ServiceUnavailableError(\n                    \"Service transport request failed.\",\n                    detail=str(exc),\n                ) from exc\n            result, delay = self._check_retry(response, attempt, max_retries)\n            if result is not None:\n                return result\n            if delay > 0:\n                await asyncio.sleep(delay)\n\n        raise ServiceUnavailableError(\"Service request failed after retry loop.\")\n\n    async def _submit_convert_task(\n        self,\n        source: SourceType,\n        options: ConvertDocumentsRequestOptions,\n        target: SubmitTarget,\n        async_client: httpx.AsyncClient,\n        request_headers: dict[str, str] | None = None,","sourceCodeStart":681,"sourceCodeEnd":717,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/service_client/_async_client.py#L681-L717","documentation":"In the async service client's retry loop, an httpx.HTTPError (connect failure, read timeout, TLS error) that is not eligible for further transport retries is converted into ServiceUnavailableError with the original exception chained as detail. This tells the caller the HTTP transport to the Docling service could not complete the request even after the configured retry policy, e.g. the service is down or unreachable.","triggerScenarios":"The Docling service URL is wrong or unreachable (connection refused); the service is overloaded and connections time out; a proxy or firewall resets connections; DNS resolution failure; retries exhausted for retryable transport errors via _transport_retry_delay returning None.","commonSituations":"Running against a local docker service that is not started; pointing the client at a stale/internal hostname; CI environments without network access to the service endpoint; service restarting during a long batch job.","solutions":["Verify the service URL and that the Docling service is up (curl the health endpoint).","If running locally, start the docling-serve container/process before submitting work.","Increase http_retries on the client to tolerate transient outages.","Check proxies, VPN, DNS, and firewall rules between client and service."],"exampleFix":"# before\nclient = DocumentConverterClient(base_url='http://localhost:5001')\nawait client.convert_file(...)  # ServiceUnavailableError: transport failed\n\n# after\n# start service first, then point at the correct port\nclient = DocumentConverterClient(base_url='http://localhost:5001', http_retries=5)\nasync with client:\n    result = await client.convert_file(...)","handlingStrategy":"retry","validationCode":"import httpx\n\nasync def service_up(url: str) -> bool:\n    try:\n        async with httpx.AsyncClient() as c:\n            r = await c.get(url.rstrip('/') + '/health')\n            return r.status_code < 500\n    except httpx.HTTPError:\n        return False","typeGuard":null,"tryCatchPattern":"from docling.service_client.exceptions import ServiceUnavailableError\n\nfor attempt in range(5):\n    try:\n        result = await client.convert_file(f)\n        break\n    except ServiceUnavailableError as e:\n        if 'transport' not in str(e):\n            raise\n        await asyncio.sleep(2 ** attempt)","preventionTips":["Start/verify the Docling service before submitting work.","Configure http_retries and sane timeouts on the client.","Add a health check at application startup."],"tags":["service-client","network","transport","retry"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}