docling-project/docling · error · ArtifactDownloadError
Too many redirects while downloading artifact.
Error message
Too many redirects while downloading artifact.
What it means
Raised as ArtifactDownloadError by the synchronous artifact download when the redirect chain exceeds MAX_ARTIFACT_DOWNLOAD_REDIRECTS (5). The client deliberately disables httpx auto-redirects and hops manually so every intermediate URL passes the SSRF validation; after 6 hops without a 200 it gives up.
Solutions
- Fetch the artifact URL manually with curl -IL to inspect the redirect chain
- Fix the artifact host configuration to serve the object directly (fewer proxy hops)
- If the chain is legitimate and longer than 5, this limit is a constant in the client — request an upstream change rather than working around the SSRF guard
Defensive patterns
Strategy: try-catch
Validate before calling
import requests
r = requests.head(artifact_url, allow_redirects=False)
hops = 0
while r.is_redirect and hops < 10:
artifact_url = r.headers['Location']
r = requests.head(artifact_url, allow_redirects=False)
hops += 1
assert hops <= 5, f'{hops} redirect hops exceeds client cap' Type guard
def is_artifact_download_error(exc: BaseException) -> bool:
return isinstance(exc, ArtifactDownloadError) Try / catch
try:
results = list(client.convert_all(sources))
except ArtifactDownloadError as exc:
if 'Too many redirects' in str(exc):
alert_ops('artifact host redirect chain too long') Prevention
- Pre-flight the artifact URL redirect chain when deploying new object-store front-ends
- Keep artifact serving behind at most a couple of proxy layers
When it happens
Trigger: An artifact URL that bounces through more than 5 redirects (auth-less CDN chains, misconfigured object-store mirrors, or a redirect loop between two hosts).
Common situations: Object-store fronted by multiple reverse proxies each adding a redirect; an intentional or accidental redirect loop; a compromised service trying to bounce the client around.
Related errors
- Artifact download redirect is missing a Location header.
- Refusing to download artifact from a non-public URL
- Access to restricted IP address not allowed
- Artifact download failed
- Artifact download failed with HTTP
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/fb70c7ce051c7df6.
Report an issue: GitHub.
Appendix: source
Thrown at docling/service_client/client.py:1910
for _ in range(MAX_ARTIFACT_DOWNLOAD_REDIRECTS + 1):
self._validate_artifact_url(url)
with client.stream("GET", url) as response:
if response.is_redirect:
url = self._next_redirect_url(url, response)
continue
if response.status_code != 200:
raise ArtifactDownloadError(
"Artifact download failed with HTTP "
f"{response.status_code}."
)
chunks: list[bytes] = []
total = 0
for chunk in response.iter_bytes():
total += len(chunk)
self._check_artifact_size(total)
chunks.append(chunk)
return b"".join(chunks)
raise ArtifactDownloadError(
"Too many redirects while downloading artifact."
)
except httpx.HTTPError as exc:
raise ArtifactDownloadError(f"Artifact download failed: {exc}") from exc
async def _download_artifact_bytes_async(self, uri: str) -> bytes:
timeout = httpx.Timeout(self._artifact_download_timeout)
try:
async with httpx.AsyncClient(
timeout=timeout, follow_redirects=False
) as client:
url = uri
for _ in range(MAX_ARTIFACT_DOWNLOAD_REDIRECTS + 1):
self._validate_artifact_url(url)
async with client.stream("GET", url) as response:
if response.is_redirect:
url = self._next_redirect_url(url, response)
continueView on GitHub (pinned to 61d76f1ff3)