docling-project/docling · error · ValueError
Unsupported URL scheme: '{scheme}'. Only http:// and https:/
Error message
Unsupported URL scheme: '{scheme}'. Only http:// and https:// are supported. What it means
When _normalize_source receives a string that fails AnyHttpUrl validation but contains '://', the client extracts the scheme and only accepts http/https; anything else (ftp, s3, file, gs, ...) raises ValueError with this message. Strings without '://' fall through to local Path validation, so this error specifically guards remote-source URLs with unsupported schemes.
Source
Thrown at docling/service_client/client.py:533
"tar.gz" if lowered.endswith(".tar.gz") else Path(name).suffix[1:].lower()
)
if extension in self._extension_to_format:
return self._extension_to_format[extension]
return InputFormat.PDF
def _normalize_source(
self, source: SourceType
) -> Path | HttpSourceRequest | DocumentStream:
if isinstance(source, (Path, HttpSourceRequest, DocumentStream)):
return source
try:
http_url = TypeAdapter(AnyHttpUrl).validate_python(source)
return HttpSourceRequest(url=str(http_url), headers={})
except ValidationError:
if "://" in source:
scheme = source.split("://", 1)[0].lower()
if scheme not in ("http", "https"):
raise ValueError(
f"Unsupported URL scheme: '{scheme}'. Only http:// and https:// are supported."
)
return TypeAdapter(Path).validate_python(source)
@staticmethod
def _validate_concurrency(value: int, *, name: str) -> int:
if value < 1 or value > MAX_CONCURRENCY_LIMIT:
raise ValueError(
f"{name} must be between 1 and {MAX_CONCURRENCY_LIMIT}, got {value}."
)
return value
@staticmethod
def _normalize_exception(exc: BaseException) -> Exception:
if isinstance(exc, Exception):
return exc
return RuntimeError(str(exc))
View on GitHub (pinned to 61d76f1ff3)
Solutions
- Download non-http sources (s3://, ftp://, gs://) yourself and pass a local Path, or generate an https presigned URL.
- For http(s) URLs, ensure they are well-formed (scheme + host).
- For local files, pass a pathlib.Path or a plain path string without '://'.
Example fix
# before
result = client.convert('s3://my-bucket/doc.pdf') # ValueError
# after
import boto3, pathlib
s3 = boto3.client('s3')
s3.download_file('my-bucket', 'doc.pdf', '/tmp/doc.pdf')
result = client.convert(pathlib.Path('/tmp/doc.pdf')) Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
def source_ok(s: str) -> bool:
if '://' not in s:
return True # treated as local path
return urlparse(s).scheme in ('http', 'https') Type guard
def is_http_url(s: str) -> bool:
from urllib.parse import urlparse
p = urlparse(s)
return p.scheme in ('http', 'https') and bool(p.netloc) Try / catch
try:
result = client.convert(url)
except ValueError as e:
if 'Unsupported URL scheme' in str(e):
local = download_to_temp(url)
result = client.convert(local) Prevention
- Convert s3://gs://ftp:// sources to local Paths or https presigned URLs first.
- Pass local files as pathlib.Path, not file:// URIs.
When it happens
Trigger: Passing 'ftp://server/file.pdf', 's3://bucket/doc.pdf', or 'file:///tmp/doc.pdf' as a source to convert(); AnyHttpUrl rejecting a malformed http URL (e.g. missing host) can also surface here; copy-pasting cloud-storage presigned URLs with their native scheme.
Common situations: Feeding S3/GCS/Azure URLs directly instead of downloading first or using an http(s) presigned URL; scripts that accept arbitrary URI inputs; Windows drive-letter strings that parse oddly.
Related errors
- API runtime requires a URL
- submit_batch() requires either 'target' or 'targets'.
- submit_batch() received both 'target' and 'targets'; supply
- Response schema mismatch — client and server versions may di
- {name} must be between 1 and {MAX_CONCURRENCY_LIMIT}, got {v
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/03ee0911191d90f2.
Report an issue: GitHub.