{"record":{"id":"c0c630afda68766d","repo":"docling-project/docling","slug":"artifact-download-failed-exc","errorCode":null,"errorMessage":"Artifact download failed: {exc}","messagePattern":"Artifact download failed: (.+?)","errorType":"exception","errorClass":"ArtifactDownloadError","httpStatus":null,"severity":"error","filePath":"docling/service_client/client.py","lineNumber":1914,"sourceCode":"                            url = self._next_redirect_url(url, response)\n                            continue\n                        if response.status_code != 200:\n                            raise ArtifactDownloadError(\n                                \"Artifact download failed with HTTP \"\n                                f\"{response.status_code}.\"\n                            )\n                        chunks: list[bytes] = []\n                        total = 0\n                        for chunk in response.iter_bytes():\n                            total += len(chunk)\n                            self._check_artifact_size(total)\n                            chunks.append(chunk)\n                        return b\"\".join(chunks)\n                raise ArtifactDownloadError(\n                    \"Too many redirects while downloading artifact.\"\n                )\n        except httpx.HTTPError as exc:\n            raise ArtifactDownloadError(f\"Artifact download failed: {exc}\") from exc\n\n    async def _download_artifact_bytes_async(self, uri: str) -> bytes:\n        timeout = httpx.Timeout(self._artifact_download_timeout)\n        try:\n            async with httpx.AsyncClient(\n                timeout=timeout, follow_redirects=False\n            ) as client:\n                url = uri\n                for _ in range(MAX_ARTIFACT_DOWNLOAD_REDIRECTS + 1):\n                    self._validate_artifact_url(url)\n                    async with client.stream(\"GET\", url) as response:\n                        if response.is_redirect:\n                            url = self._next_redirect_url(url, response)\n                            continue\n                        if response.status_code != 200:\n                            raise ArtifactDownloadError(\n                                \"Artifact download failed with HTTP \"\n                                f\"{response.status_code}.\"","sourceCodeStart":1896,"sourceCodeEnd":1932,"githubUrl":"https://github.com/docling-project/docling/blob/61d76f1ff3f8428065465889f7b4577da7df704c/docling/service_client/client.py#L1896-L1932","documentation":"Raised as ArtifactDownloadError wrapping any httpx.HTTPError raised by the synchronous artifact download: connection failures, DNS errors, TLS problems, or read timeouts (bounded by artifact_download_timeout, default 60s). The original exception is chained via 'from exc' so the cause is inspectable.","triggerScenarios":"Artifact host unreachable, DNS resolution failure, TLS certificate error, or a slow object store exceeding artifact_download_timeout during convert() materialization.","commonSituations":"Corporate proxies blocking the object-store domain; ephemeral DNS failures in containers; large artifacts on slow links hitting the 60s default; self-signed certificates on internal MinIO deployments.","solutions":["Increase artifact_download_timeout in the client constructor if artifacts are large or the link is slow","Verify connectivity: curl the presigned URL from the same machine/container","Configure proxy environment variables (HTTPS_PROXY) or trust the internal CA if TLS fails"],"exampleFix":"// before\nclient = DoclingServiceClient(url, artifact_download_timeout=60.0)\n\n// after\nclient = DoclingServiceClient(url, artifact_download_timeout=300.0)","handlingStrategy":"retry","validationCode":"import socket\nfrom urllib.parse import urlparse\nhost = urlparse(artifact_url).hostname\nassert host and socket.gethostbyname(host), 'artifact host unresolvable'","typeGuard":"def is_artifact_download_error(exc: BaseException) -> bool:\n    return isinstance(exc, ArtifactDownloadError)","tryCatchPattern":"try:\n    results = list(client.convert_all(sources))\nexcept ArtifactDownloadError as exc:\n    if 'timeout' in str(exc).lower() or 'connect' in str(exc).lower():\n        time.sleep(5)\n        retry_with_backoff()","preventionTips":["Size artifact_download_timeout to your worst-case artifact size divided by link speed","Verify proxy/CA config before running batch conversions"],"tags":["network","timeout","tls","artifact-download"],"backgroundTag":null,"analyzedSha":"61d76f1ff3f8428065465889f7b4577da7df704c","analyzedAt":"2026-08-14T23:53:18.727Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}