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

  1. Download non-http sources (s3://, ftp://, gs://) yourself and pass a local Path, or generate an https presigned URL.
  2. For http(s) URLs, ensure they are well-formed (scheme + host).
  3. 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

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


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