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.

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)
                            continue

View on GitHub (pinned to 61d76f1ff3)

Solutions

  1. Fetch the artifact URL manually with curl -IL to inspect the redirect chain
  2. Fix the artifact host configuration to serve the object directly (fewer proxy hops)
  3. 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

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


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