pypa/pip · error · IDNAError
Domain too long
Error message
Domain too long
What it means
Raised by idna.encode and idna.decode when the input domain string exceeds the maximum allowed length. The check has two layers: a fast guard at _max_input_length (1024 chars) to reject absurdly long strings early, and a standards-based check via valid_string_length enforcing RFC 1035's 253-octet (254 with trailing dot) DNS limit. Domains exceeding these limits cannot be valid DNS names.
Solutions
- Validate the hostname length before calling encode/decode: reject if len(host) > 253.
- Ensure you are passing only the hostname, not the full URL path or query string.
- Truncate or reject oversized input at the data-entry boundary.
- Use urllib.parse.urlsplit to extract just the hostname before IDNA processing.
Example fix
# before
idna.encode('a' * 300 + '.example.com') # raises Domain too long
# after
host = 'a' * 300 + '.example.com'
if len(host) > 253:
raise ValueError(f'Hostname too long: {len(host)} > 253')
idna.encode(host) Defensive patterns
Strategy: validation
Validate before calling
MAX_DNS_LENGTH = 253
def is_valid_domain_length(domain: str) -> bool:
trailing = domain.endswith('.')
effective = domain.rstrip('.') if trailing else domain
max_len = 254 if trailing else 253
return len(effective) <= max_len and len(domain) <= 1024 Type guard
def is_valid_domain_length(domain: str) -> bool:
return 0 < len(domain) <= 253 or (0 < len(domain) <= 254 and domain.endswith('.')) Try / catch
from idna.core import IDNAError
try:
result = idna.encode(domain)
except IDNAError as e:
if 'too long' in str(e).lower():
raise ValueError(f'Domain exceeds DNS length limit: {len(domain)}')
raise Prevention
- Validate hostname length (<=253 chars) before IDNA processing.
- Extract only the hostname from URLs before encoding — not the full URL.
- Cap user-supplied domain input at the application boundary.
When it happens
Trigger: Calling idna.encode() or idna.decode() with a string longer than 253 octets (or 254 with trailing dot), or longer than 1024 characters. Also raised after UTS#46 remapping if the result exceeds limits.
Common situations: User-supplied or generated domain strings that are unbounded; accidentally passing a full URL or path instead of just the hostname; concatenated subdomains; test data with very long random strings.
Related errors
- Empty domain
- Empty label
- Unsupported error handling
- At least one hash must be provided
- Cannot determine sdist filename
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/3cd678ae356bc3b9.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/idna/core.py:625
rendered as Unicode. Matches the per-label recovery prescribed
by UTS #46 §4 and the WHATWG URL "domain to Unicode" algorithm.
:returns: The decoded domain as a Unicode string.
:raises IDNAError: If the input is not valid ASCII, contains an
invalid label, or is empty.
"""
if not isinstance(s, str):
try:
s = str(s, "ascii")
except (UnicodeDecodeError, TypeError) as err:
raise IDNAError("Invalid ASCII in A-label") from err
if len(s) > _max_input_length:
raise IDNAError("Domain too long")
if uts46:
s = uts46_remap(s, std3_rules, False)
# Reject inputs that exceed the maximum DNS domain length up-front
# to avoid expensive computation on long inputs.
if not valid_string_length(s, trailing_dot=True):
raise IDNAError("Domain too long")
trailing_dot = False
result = []
labels = s.split(".") if strict else _unicode_dots_re.split(s)
if not labels or labels == [""]:
raise IDNAError("Empty domain")
if not labels[-1]:
del labels[-1]
trailing_dot = True
for label in labels:
try:
u = ulabel(label)
except IDNAError:
if display and label[:4].lower() == "xn--":
u = label.lower()
else:
raise
if u:
result.append(u)View on GitHub (pinned to f399c37189)