pypa/pip · error · IDNAError
Empty label
Error message
Empty label
What it means
Raised by idna.encode and idna.decode when an individual label within the domain decodes/encodes to an empty string. This happens when the domain contains consecutive label separators (e.g. 'a..b.com') creating a zero-length label, or a leading/trailing dot pattern that yields an empty intermediate label. Each label must be non-empty per IDNA/DNS rules.
Solutions
- Sanitize the domain by removing empty labels: host = '.'.join(p for p in host.split('.') if p).
- Validate the domain has no consecutive dots before IDNA processing.
- Reject input containing leading/trailing/consecutive dots at the validation boundary.
Example fix
# before
idna.encode('example..com') # raises Empty label
# after
host = '.'.join(label for label in 'example..com'.split('.') if label)
idna.encode(host) # 'example.com' Defensive patterns
Strategy: validation
Validate before calling
def sanitize_domain(domain: str) -> str:
labels = domain.split('.')
cleaned = '.'.join(label for label in labels if label)
if not cleaned:
raise ValueError('Domain has no valid labels')
return cleaned Type guard
def has_no_empty_labels(domain: str) -> bool:
labels = domain.split('.')
return all(label for label in labels) if labels else False Try / catch
from idna.core import IDNAError
try:
result = idna.encode(domain)
except IDNAError:
domain = '.'.join(l for l in domain.split('.') if l)
result = idna.encode(domain) Prevention
- Strip empty labels from domains before IDNA processing.
- Reject domains with consecutive dots at input validation.
- Sanitize concatenated domain parts by filtering empty strings.
When it happens
Trigger: Calling idna.encode('example..com') (double dot), idna.encode('.example.com') with strict processing that yields an empty first label, or idna.decode on a Punycode string with empty labels.
Common situations: Concatenating domain parts without checking for empty segments; user typos with double dots; malformed data from upstream; string manipulation that leaves empty labels.
Related errors
- Domain too long
- Empty domain
- 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/48bc01cc13e178d4.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/idna/core.py:645
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)
else:
raise IDNAError("Empty label")
if trailing_dot:
result.append("")
return ".".join(result)
View on GitHub (pinned to f399c37189)