pypa/pip · error · IDNAError
Empty domain
Error message
Empty domain
What it means
Raised by encode() (core.py:564) when splitting the input on label separators yields no labels at all, or only a single empty label — i.e. the input is the empty string (''), a string containing only separators, or collapses to [''] after split. An empty domain has no encodable content.
Source
Thrown at src/pip/_vendor/idna/core.py:564
try:
s = str(s, "ascii")
except (UnicodeDecodeError, TypeError) as err:
raise IDNAError("should pass a unicode string to the function rather than a byte string.") from err
if len(s) > _max_input_length:
raise IDNAError("Domain too long")
if uts46:
s = uts46_remap(s, std3_rules, transitional)
# 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 labels[-1] == "":
del labels[-1]
trailing_dot = True
for label in labels:
s = alabel(label)
if s:
result.append(s)
else:
raise IDNAError("Empty label")
if trailing_dot:
result.append(b"")
s = b".".join(result)
if not valid_string_length(s, trailing_dot):
raise IDNAError("Domain too long")
return s
def decode(View on GitHub (pinned to d7d0d0a394)
Solutions
- Check for a falsy/empty hostname before calling encode() and handle it as an application-level error.
- Default to a sane fallback domain or reject the request when the hostname is missing.
- Strip then validate: if not domain: raise ValueError('hostname required').
Example fix
// before
idna.encode(host or '') # host is None -> ''
// after
if not host:
raise ValueError('hostname is required')
idna.encode(host) Defensive patterns
Strategy: validation
Validate before calling
def is_non_empty_domain(domain: str) -> bool:
return isinstance(domain, str) and domain.strip() != ''
if not is_non_empty_domain(domain):
raise ValueError('hostname is required')
encoded = idna.encode(domain) Type guard
def is_non_empty_str(s) -> bool:
return isinstance(s, str) and s != '' Try / catch
import idna
try:
encoded = idna.encode(domain)
except idna.IDNAError as err:
if 'Empty domain' in str(err):
# missing hostname; fall back or reject
raise ValueError('hostname is required') from err
raise Prevention
- Check for falsy/empty hostnames before encoding and handle as an app-level error.
- Validate urlsplit(url).hostname is not None for URL inputs.
- Default missing Host headers to a sensible fallback or reject the request.
When it happens
Trigger: Calling idna.encode(''), idna.encode('.'), idna.encode('..'), or encode() on a variable that resolved to an empty string (e.g. a missing Host header, an uninitialised config field, or urlsplit(url).hostname returning None converted to '').
Common situations: Missing/empty Host headers in HTTP requests, uninitialised config values, env vars not set defaulting to '', URL parsing that yields an empty hostname for a relative URL, or sanitisation that strips everything.
Related errors
- Empty label
- Codepoint {_unot(cp_value)} at position {pos + 1} of {label!
- Domain too long
- Codepoint {_unot(cp_value)} not allowed at position {pos + 1
- Malformed A-label, no Punycode eligible content found
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/7b7d7da809ff268b.json.
Report an issue: GitHub.