docling-project/docling · error · ValueError
ZIP URLs are not accepted on the convert endpoint
Error message
ZIP URLs are not accepted on the convert endpoint
What it means
The HttpSourceRequest model used by the convert endpoints runs a field validator on url that rejects any HTTP URL whose path (case-insensitive, query string stripped) ends in '.zip'. The convert endpoint processes single documents, while ZIP archives are handled by a different flow (the service defines a zip target/response container), so ZIP URLs are refused at request validation time.
Source
Thrown at docling/datamodel/service/requests.py:57
class FileSourceRequest(FileSource):
kind: Literal["file"] = "file"
class AnyHttpSourceRequest(HttpSource):
kind: Literal["http"] = "http"
class HttpSourceRequest(AnyHttpSourceRequest):
"""HTTP source for convert endpoints — rejects ZIP URLs."""
@field_validator("url")
@classmethod
def reject_zip_url(cls, value: AnyHttpUrl) -> AnyHttpUrl:
path = str(value).lower().split("?", maxsplit=1)[0]
if path.endswith(".zip"):
raise ValueError("ZIP URLs are not accepted on the convert endpoint")
return value
class S3SourceRequest(S3Coordinates):
kind: Literal["s3"] = "s3"
class AzureBlobSourceRequest(AzureBlobCoordinates):
kind: Literal["azure_blob"] = "azure_blob"
class GoogleCloudStorageSourceRequest(GoogleCloudStorageCoordinates):
kind: Literal["google_cloud_storage"] = "google_cloud_storage"
class GoogleDriveSourceRequest(GoogleDriveCoordinates):
kind: Literal["google_drive"] = "google_drive"
View on GitHub (pinned to 61d76f1ff3)
Solutions
- Use the endpoint/flow that accepts ZIP archives instead of the convert endpoint.
- If the ZIP contains one document, download and extract it client-side, then send the extracted file (or its extracted URL) to convert.
- If the .zip suffix is incidental (URL rewrite), serve the file under a URL that reflects its real extension.
Example fix
# before
req = {
"sources": [{"kind": "http", "url": "https://cdn.example.com/batch.zip"}],
"options": {...},
}
# after
# extract locally, then convert each document
with zipfile.ZipFile(download("https://cdn.example.com/batch.zip")) as zf:
for name in zf.namelist():
convert_bytes(zf.read(name)) Defensive patterns
Strategy: type-guard
Validate before calling
from urllib.parse import urlparse
def is_zip_url(url: str) -> bool:
return urlparse(url).path.lower().endswith(".zip")
if is_zip_url(source_url):
raise ValueError("convert endpoint rejects .zip URLs; use the ZIP ingest flow") Type guard
def is_convertible_http_url(url: str) -> bool:
return not urlparse(url).path.lower().endswith(".zip") Try / catch
try:
resp = client.convert(sources=[{"kind": "http", "url": url}])
except ValidationError as e:
if "ZIP URLs" in str(e):
# extract locally or switch to the ZIP-capable flow
...
raise Prevention
- Filter or pre-download .zip links before submitting to convert.
- Remember the check ignores query strings and URL case.
When it happens
Trigger: Submitting a convert request whose http source url is e.g. 'https://example.com/docs/batch.ZIP' or '.../file.zip?token=abc'. The validator lowercases the URL and strips the query before checking the '.zip' suffix, so case tricks and query strings do not bypass it.
Common situations: Pointing the convert endpoint at a bulk-download ZIP of many documents; a CDN or export link that ends in .zip even for a single file; porting a curl example from the ZIP-ingest endpoint to the convert endpoint.
Related errors
- Invalid JSON for nested config field: {exc}
- The parameters picture_description_local and picture_descrip
- The parameters vlm_pipeline_model, vlm_pipeline_model_local
- Cannot specify both vlm_pipeline_preset and vlm_pipeline_cus
- Cannot mix legacy VLM options (vlm_pipeline_model*) with new
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/0b9f927e4e6dd305.
Report an issue: GitHub.