pypa/pip · error · IDNAError

Label too long

Error message

Label too long

What it means

Raised by idna.check_bidi when the input label handed to the Bidi Rule check exceeds _max_input_length (1024 characters). It is a defensive guard placed at the top of check_bidi to reject pathologically long inputs before any per-codepoint work, distinct from the DNS 63-octet label limit enforced elsewhere.

Source

Thrown at src/pip/_vendor/idna/core.py:116

def check_bidi(label: str, check_ltr: bool = False) -> bool:
    """Validate the Bidi Rule from :rfc:`5893` for a single label.

    The Bidi Rule constrains how bidirectional characters (Hebrew, Arabic,
    etc.) may appear within a label. By default the check is only applied
    when the label contains at least one right-to-left character (Unicode
    bidirectional categories ``R``, ``AL``, or ``AN``); set ``check_ltr``
    to ``True`` to apply it to LTR-only labels as well.

    :param label: The label to validate, as a Unicode string.
    :param check_ltr: If ``True``, apply the rules even when the label
        contains no RTL characters.
    :returns: ``True`` if the label satisfies the Bidi Rule.
    :raises IDNABidiError: If any of Bidi Rule conditions 1-6 are violated,
        or if the directional category of a codepoint cannot be determined.
    """
    if len(label) > _max_input_length:
        raise IDNAError("Label too long")
    # Bidi rules should only be applied if string contains RTL characters
    bidi_label = False
    for idx, cp in enumerate(label, 1):
        direction = unicodedata.bidirectional(cp)
        if direction == "":
            # String likely comes from a newer version of Unicode
            raise IDNABidiError(f"Unknown directionality in label {label!r} at position {idx}")
        if direction in _bidi_rtl_categories:
            bidi_label = True
    if not bidi_label and not check_ltr:
        return True

    # Bidi rule 1
    direction = unicodedata.bidirectional(label[0])
    if direction in _bidi_rtl_first:
        rtl = True
    elif direction == "L":
        rtl = False

View on GitHub (pinned to d7d0d0a394)

Solutions

  1. Validate the input length before calling idna: reject or truncate labels longer than 63 characters (the real DNS limit) rather than 1024.
  2. Split the domain into labels on '.' (and the Unicode dot equivalents) and encode each label separately.
  3. Sanitize upstream so hostnames come from a bounded, trusted source.

Example fix

# before
idna.encode(user_supplied_long_string)  # Label too long

# after
if len(label) > 63:
    raise ValueError('label exceeds DNS 63-octet limit')
idna.encode(label)
Defensive patterns

Strategy: validation

Validate before calling

MAX_LABEL = 63
def validate_label(label: str) -> str:
    if len(label) > MAX_LABEL:
        raise ValueError(f'label too long ({len(label)} > {MAX_LABEL})')
    return label

Type guard

def is_valid_label_length(label: str) -> bool:
    return 0 < len(label) <= 63

Try / catch

from idna import IDNAError
try:
    idna.check_bidi(label)
except IDNAError as e:
    if 'too long' in str(e).lower():
        raise ValueError('label exceeds length limit') from e
    raise

Prevention

When it happens

Trigger: Calling idna.encode/decode/check_bidi/alabel/ulabel with a single label longer than 1024 chars; passing an unsplit full domain string (with no dot separators) into a code path that ends in check_bidi.

Common situations: User input or scraped data containing a huge unbroken token being treated as a hostname; a bug in a URL parser that fails to split labels before IDNA encoding; fuzzing / property-based tests feeding arbitrary long strings.

Related errors


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