encode/httpx · error · InvalidURL

URL too long

Error message

URL too long

What it means

Raised by urlparse when the input URL string exceeds MAX_URL_LENGTH (65536 characters). httpx enforces a hard cap to prevent pathological memory/CPU use during parsing and percent-encoding. It is raised as InvalidURL before any component is examined.

Source

Thrown at httpx/_urlparse.py:219

        authority = self.authority
        return "".join(
            [
                f"{self.scheme}:" if self.scheme else "",
                f"//{authority}" if authority else "",
                self.path,
                f"?{self.query}" if self.query is not None else "",
                f"#{self.fragment}" if self.fragment is not None else "",
            ]
        )


def urlparse(url: str = "", **kwargs: str | None) -> ParseResult:
    # Initial basic checks on allowable URLs.
    # ---------------------------------------

    # Hard limit the maximum allowable URL length.
    if len(url) > MAX_URL_LENGTH:
        raise InvalidURL("URL too long")

    # If a URL includes any ASCII control characters including \t, \r, \n,
    # then treat it as invalid.
    if any(char.isascii() and not char.isprintable() for char in url):
        char = next(char for char in url if char.isascii() and not char.isprintable())
        idx = url.find(char)
        error = (
            f"Invalid non-printable ASCII character in URL, {char!r} at position {idx}."
        )
        raise InvalidURL(error)

    # Some keyword arguments require special handling.
    # ------------------------------------------------

    # Coerce "port" to a string, if it is provided as an integer.
    if "port" in kwargs:
        port = kwargs["port"]
        kwargs["port"] = str(port) if isinstance(port, int) else port

View on GitHub (pinned to b5addb64f0)

Solutions

  1. Move large payloads from the URL to the request body (POST/PUT) or use multipart upload.
  2. Shorten the URL by sending IDs/filters in a JSON body or in fewer batched requests.
  3. Compress large query values (gzip+base64) if a GET is genuinely required.
  4. Pre-check length: if len(url) > 65536: switch to POST.

Example fix

// before
url = "https://api.example.com/items?ids=" + ",".join(str(i) for i in range(10**6))
client.get(url)  # InvalidURL: URL too long

// after
client.post("https://api.example.com/items", json={"ids": list(range(10**6))})
Defensive patterns

Strategy: validation

Validate before calling

from httpx._urlparse import MAX_URL_LENGTH

def safe_url(url: str) -> str:
    if len(url) > MAX_URL_LENGTH:
        raise ValueError(f"URL length {len(url)} exceeds {MAX_URL_LENGTH}; use POST")
    return url

client.get(safe_url(maybe_huge_url))

Type guard

def is_url_length_ok(url: str, limit: int = 65536) -> bool:
    return len(url) <= limit

Try / catch

from httpx import InvalidURL

try:
    client.get(url)
except InvalidURL as e:
    if "too long" in str(e):
        # switch to a body-based request
        client.post(endpoint, json=payload)
    else:
        raise

Prevention

When it happens

Trigger: Calling httpx.URL(huge_string), httpx.Client().get(gigantic_url), or building a URL whose query string is assembled from a very large payload (e.g. base64-ing a file into a GET parameter).

Common situations: Encoding binary/file data as a query parameter instead of using a POST body; concatenating many filter parameters into a GET URL; passing a data: URL by mistake; URL built from a huge comma-separated ID list.

Related errors


AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04). Data as JSON: /data/errors/72b8af6e83026e4e.json. Report an issue: GitHub.