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

  1. Check for a falsy/empty hostname before calling encode() and handle it as an application-level error.
  2. Default to a sane fallback domain or reject the request when the hostname is missing.
  3. 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

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


AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04). Data as JSON: /data/errors/7b7d7da809ff268b.json. Report an issue: GitHub.