roboflow/supervision · error · ValueError

Unsupported URL scheme {parsed_url.scheme} in {url}. Only HT

Error message

Unsupported URL scheme {parsed_url.scheme} in {url}. Only HTTP and HTTPS URLs are supported.

What it means

Raised during URL validation (e.g. for downloading assets) when the parsed URL scheme is not http or https. The validator explicitly allows only these two schemes, so ftp://, file://, gs://, s3://, or scheme-less strings are rejected even though `requests` might partially accept them. This is a security and capability boundary: the downloader only speaks HTTP(S).

Source

Thrown at src/supervision/utils/file.py:44

    Raises:
        ValueError: If the URL is invalid or uses an unsupported scheme.
    """
    try:
        original_parsed_url = urllib.parse.urlparse(url)
        if "\\" in original_parsed_url.netloc:
            raise ValueError("URL authority contains a backslash")

        prepared_request = requests.Request(method="GET", url=url).prepare()
        prepared_url = prepared_request.url
        if prepared_url is None:
            raise ValueError("prepared URL is empty")

        parsed_url = urllib.parse.urlparse(prepared_url)
    except (requests.RequestException, ValueError) as error:
        raise ValueError(f"Invalid URL {url!r}: {error}") from error

    if parsed_url.scheme not in {"http", "https"}:
        raise ValueError(
            f"Unsupported URL scheme {parsed_url.scheme!r} in {url!r}. "
            "Only HTTP and HTTPS URLs are supported."
        )
    if parsed_url.hostname is None:
        raise ValueError(f"Invalid URL {url!r}: no host supplied.")

    return prepared_url


def _download_to_file(
    url: str, target: Path, *, timeout: float = 30.0, stream: bool = False
) -> None:
    """
    Download `url` to `target` atomically using a temporary file and `os.replace`.

    Args:
        url: HTTP(S) URL to download.
        target: Destination file path. Parent directories are created as needed.

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Use http:// or https:// URLs only.
  2. For local files, call the local-path code path (pass a Path) instead of the URL downloader.
  3. For cloud storage, download with the native SDK first, then pass the local file.

Example fix

# before
url = 's3://my-bucket/model.pt'
# after
# download via aws cli / boto3 to './model.pt', then pass the local path
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse
scheme = urlparse(url).scheme
assert scheme in {'http', 'https'}, f'unsupported scheme: {scheme!r}'

Type guard

def is_http_url(url: str) -> bool:
    return urlparse(url).scheme in {'http', 'https'}

Prevention

When it happens

Trigger: Passing `'ftp://host/file.zip'`, `'file:///data/model.pt'`, or `'s3://bucket/key'` to a supervision download API; a config value without a scheme that parses to something unexpected.

Common situations: Porting configs from tools that accept cloud-storage URIs; local-development overrides pointing at files on disk; copy-pasting mirror URLs (e.g. an internal Artifactory ftp mirror).

Related errors


AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15). Data as JSON: /api/errors/078ba0c277008855. Report an issue: GitHub.