encode/httpx · error · InvalidURL
Invalid IPv4 address: {host!r}
Error message
Invalid IPv4 address: {host!r} What it means
Raised by encode_host when the host looks like an IPv4 dotted-quad (matches ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$) but ipaddress.IPv4Address() rejects it (e.g. an octet > 255 or negative). Each octet must be a valid 0-255 decimal; leading zeros are also rejected by modern Python.
Source
Thrown at httpx/_urlparse.py:361
parsed_query,
parsed_frag,
)
def encode_host(host: str) -> str:
if not host:
return ""
elif IPv4_STYLE_HOSTNAME.match(host):
# Validate IPv4 hostnames like #.#.#.#
#
# From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2
#
# IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet
try:
ipaddress.IPv4Address(host)
except ipaddress.AddressValueError:
raise InvalidURL(f"Invalid IPv4 address: {host!r}")
return host
elif IPv6_STYLE_HOSTNAME.match(host):
# Validate IPv6 hostnames like [...]
#
# From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2
#
# "A host identified by an Internet Protocol literal address, version 6
# [RFC3513] or later, is distinguished by enclosing the IP literal
# within square brackets ("[" and "]"). This is the only place where
# square bracket characters are allowed in the URI syntax."
try:
ipaddress.IPv6Address(host[1:-1])
except ipaddress.AddressValueError:
raise InvalidURL(f"Invalid IPv6 address: {host!r}")
return host[1:-1]
elif host.isascii():View on GitHub (pinned to b5addb64f0)
Solutions
- Validate the IP with ipaddress.IPv4Address(host) before building the URL.
- Clamp generated octets to 0-255 in any code that synthesizes IPs.
- Strip whitespace/dots from user input before parsing.
- If a hostname (not an IP) is intended, ensure it does not match the dotted-quad regex.
Example fix
// before
url = httpx.URL("http://10.0.0.300/") # Invalid IPv4 address
// after
import ipaddress
host = "10.0.0.300"
ipaddress.IPv4Address(host) # raises early, predictable
url = httpx.URL("http://10.0.0.30/") Defensive patterns
Strategy: validation
Validate before calling
import ipaddress
def safe_ipv4(host: str) -> str:
ipaddress.IPv4Address(host) # raises AddressValueError early
return host
url = httpx.URL(host=safe_ipv4(user_host)) Type guard
import ipaddress
def is_valid_ipv4(host: str) -> bool:
try:
ipaddress.IPv4Address(host)
return True
except ipaddress.AddressValueError:
return False Try / catch
from httpx import InvalidURL
try:
url = httpx.URL(f"http://{host}/")
except InvalidURL as e:
if "Invalid IPv4" in str(e):
# fall back to DNS hostname or reject input
raise ValueError(f"Bad IP from user: {host!r}") from e
raise Prevention
- Always validate IPs with the ipaddress module before use.
- Clamp generated octets to 0-255.
- Avoid leading-zero octet notation.
When it happens
Trigger: httpx.URL('http://999.0.0.1/'), httpx.URL(host='10.0.0.256'), or constructing a URL with host='192.168.1.300'.
Common situations: Off-by-one IP generation; user-typed IP with a typo; arithmetic that produces an octet > 255; legacy code emitting leading-zero octets like '010.0.0.1'.
Related errors
- Invalid IPv6 address: {host!r}
- Proxy protocol must be either 'http', 'https', 'socks5', or
- URL too long
- Invalid non-printable ASCII character in URL, {char!r} at po
- URL component '{key}' too long
AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04).
Data as JSON: /data/errors/435d08526a962d73.json.
Report an issue: GitHub.