psf/requests · error · InvalidURL

URL has an invalid label.

Error message

URL has an invalid label.

What it means

An `InvalidURL` raised in `prepare_url` when the hostname contains non-ASCII characters and IDNA encoding fails. Requests attempts to convert internationalized domain names to punycode via `_get_idna_encoded_host`; if the idna library raises (label too long, empty label, disallowed code points), the host cannot form a valid DNS name and the URL is rejected.

Source

Thrown at src/requests/models.py:532

        if not scheme:
            raise MissingSchema(
                f"Invalid URL {url!r}: No scheme supplied. "
                f"Perhaps you meant https://{url}?"
            )

        if not host:
            raise InvalidURL(f"Invalid URL {url!r}: No host supplied")

        # In general, we want to try IDNA encoding the hostname if the string contains
        # non-ASCII characters. This allows users to automatically get the correct IDNA
        # behaviour. For strings containing only ASCII characters, we need to also verify
        # it doesn't start with a wildcard (*), before allowing the unencoded hostname.
        if not unicode_is_ascii(host):
            try:
                host = self._get_idna_encoded_host(host)
            except UnicodeError:
                raise InvalidURL("URL has an invalid label.")
        elif host.startswith(("*", ".")):
            raise InvalidURL("URL has an invalid label.")

        # Carefully reconstruct the network location
        netloc = auth or ""
        if netloc:
            netloc += "@"
        netloc += host
        if port:
            netloc += f":{port}"

        # Bare domains aren't valid URLs.
        if not path:
            path = "/"

        if isinstance(params, (str, bytes)):
            params = to_native_string(params)

View on GitHub ↗ (pinned to 414f0513c3)

Solutions

  1. Inspect the hostname bytes: `print(ascii(urlparse(url).hostname))` to reveal hidden unicode characters, then strip or fix them.
  2. Sanitize input URLs (strip whitespace and zero-width/invisible characters) before requesting.
  3. If the domain is genuinely internationalized, pre-encode it yourself with `idna.encode(host)` to get a specific error explaining which label is invalid.

Example fix

# before (host contains a zero-width space)
requests.get('https://exam\u200bple.com')

# after
url = raw_url.replace('\u200b', '').strip()
requests.get(url)
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse
host = urlparse(url).hostname or ""
# each DNS label must be 1-63 chars
if not all(0 < len(label) <= 63 for label in host.split(".")):
    raise ValueError(f"invalid hostname in {url!r}")
host.encode("idna")  # raises UnicodeError for invalid IDNA labels

Try / catch

from requests.exceptions import InvalidURL
try:
    resp = requests.get(url)
except InvalidURL as e:
    if "invalid label" in str(e).lower():
        ...  # non-ASCII host failed IDNA encoding
    raise

Prevention

When it happens

Trigger: Requesting a URL whose host has a non-ASCII label that violates IDNA rules — e.g. a label over 63 characters, an empty label ('http://exämple..com'), disallowed characters or misplaced combining marks. Only reached when `unicode_is_ascii(host)` is False (src/requests/models.py:528).

Common situations: URLs scraped from web pages or user input containing lookalike/unicode characters; invisible characters (zero-width space, non-breaking space) pasted into a hostname from a document or chat; malformed internationalized domains in datasets.

Related errors


AI-assisted analysis of psf/requests@414f0513c3 (2026-07-31). Data as JSON: /data/errors/3ff3be6e08ec3d99.json. Report an issue: GitHub ↗.