{"id":244,"library":"idna","title":"IDNA — Internationalized Domain Names in Applications","description":"idna implements the Internationalized Domain Names in Applications (IDNA 2008, RFC 5891) protocol and Unicode IDNA Compatibility Processing (UTS #46) for Python. It is the modern replacement for the built-in encodings.idna module, which only supports the obsolete IDNA 2003 standard. Current version is 3.11 (Python 3.8+); releases are irregular but active, with security patches and Unicode data updates driving most releases.","status":"active","version":"3.11","language":"python","source_language":"en","source_url":"https://github.com/kjd/idna","tags":["dns","domain-names","idna","unicode","networking","encoding"],"install":[{"cmd":"pip install idna","lang":"bash","label":"PyPI"}],"dependencies":[],"imports":[{"note":"encodings.idna is the stdlib IDNA 2003 module; it produces different (incorrect by modern standards) results. Use the idna package instead.","wrong":"import encodings.idna; encodings.idna.ToASCII('例え.jp')","symbol":"encode","correct":"import idna; idna.encode('例え.jp')"},{"note":"All conversion errors inherit from idna.IDNAError; more specific subclasses are idna.IDNABidiError, idna.InvalidCodepoint, and idna.InvalidCodepointContext.","symbol":"IDNAError","correct":"from idna.core import InvalidCodepoint"},{"note":"The registered codec name changed to 'idna2008' (not 'idna') because overriding the system 'idna' codec was broken. Using 'idna' as the codec name will invoke the stdlib IDNA 2003 codec, not this library.","wrong":"'例え.jp'.encode('idna')","symbol":"codec","correct":"import idna.codec; '例え.jp'.encode('idna2008')"},{"note":"Drop-in shim that maps encodings.idna function signatures (ToASCII/ToUnicode) to IDNA 2008 equivalents. Substitute the import and no other code changes are needed.","symbol":"compat","correct":"import idna.compat"}],"quickstart":{"code":"import idna\n\n# Encode a Unicode domain to ACE/A-label bytes\nacе_label = idna.encode('ドメイン.テスト')\nprint(ace_label)          # b'xn--eckwd4c7c.xn--zckzah'\n\n# Decode ACE back to Unicode\nunicode_domain = idna.decode('xn--eckwd4c7c.xn--zckzah')\nprint(unicode_domain)     # ドメイン.テスト\n\n# Capital letters are rejected by IDNA 2008 strict mode;\n# pass uts46=True to enable UTS #46 case-folding pre-processing.\nace_uts46 = idna.encode('Königsgäßchen', uts46=True)\nprint(ace_uts46)          # b'xn--knigsgchen-b4a3dun'\n\n# Per-label helpers\nprint(idna.alabel('例え'))   # b'xn--r8jz45g'\nprint(idna.ulabel(b'xn--r8jz45g'))  # 例え\n\n# Codec interface (import idna.codec to register it first)\nimport idna.codec\nencoded = '例え.jp'.encode('idna2008')   # codec name is 'idna2008', NOT 'idna'\nprint(encoded)            # b'xn--r8jz45g.jp'\n\n# Error handling\ntry:\n    idna.encode('Königsgäßchen')   # strict mode rejects uppercase\nexcept idna.core.InvalidCodepoint as e:\n    print(f'Encoding error: {e}')\n","lang":"python","description":"Encode a Unicode domain to ASCII-compatible encoding (A-label) and decode back; handle mixed-case input with uts46=True."},"warnings":[{"fix":"Pin to idna<3 for Python 2. For Python 3, use idna>=3.0.","message":"idna v3.0 dropped Python 2 support entirely. Use 'idna<3' in requirements for Python 2 applications.","severity":"breaking","affected_versions":"<3.0"},{"fix":"import idna.codec; domain.encode('idna2008')","message":"The string codec name is 'idna2008', NOT 'idna'. After 'import idna.codec', use str.encode('idna2008'). Using 'idna' as the codec name silently invokes the stdlib IDNA 2003 codec and produces wrong results for many domains.","severity":"breaking","affected_versions":">=3.x"},{"fix":"domain = domain.lstrip('.')","message":"Dot-prefixed domains (e.g. '.example.com') are no longer accepted as valid. They raise IDNAError. Strip leading dots before calling encode().","severity":"breaking","affected_versions":">=2.6"},{"fix":"Remove the transitional=True/False argument from all encode() calls.","message":"The 'transitional' keyword argument to encode() no longer has any effect because Unicode 16.0.0 removed transitional processing. It will be removed in a future release.","severity":"deprecated","affected_versions":">=3.10"},{"fix":"idna.encode(domain, uts46=True) for user-supplied domains; idna.encode(domain) only for already-normalized lowercase labels.","message":"Uppercase and mixed-case labels raise InvalidCodepoint in strict (default) IDNA 2008 mode. Pass uts46=True to enable UTS #46 case-folding, which silently lowercases the input before conversion.","severity":"gotcha","affected_versions":"all"},{"fix":"Upgrade to idna>=3.7 immediately if processing untrusted domain names.","message":"CVE-2024-3651 (fixed in v3.7): specially crafted inputs to encode() caused catastrophic ReDoS-style CPU consumption. Any deployment on untrusted input must be on >=3.7.","severity":"gotcha","affected_versions":"<3.7"},{"fix":"Catch IDNAError and fall back to encodings.idna only when emoji/symbol domain support is explicitly required.","message":"Emoji and symbol domains are expressly prohibited by IDNA 2008 and will raise an exception. There is no flag to allow them. Fall back to encodings.idna (IDNA 2003) only as a last resort for legacy emoji domains.","severity":"gotcha","affected_versions":"all"},{"fix":"Ensure all variables are assigned a value before they are referenced or used in operations (e.g., 'ace_label = idna.encode(domain_name)' instead of just 'print(ace_label)').","message":"A NameError occurred because a variable was used before it was defined. This is a fundamental Python programming error, not specific to the 'idna' library.","severity":"gotcha","affected_versions":"all"},{"fix":"Ensure all variables are defined before they are used. Carefully check variable names for typos, especially when copying text or dealing with visually similar Unicode characters. It is recommended to use standard ASCII characters for variable names to avoid such confusion.","message":"A NameError occurred due to an undefined variable 'ace_label'. The Python interpreter's suggestion of 'acе_label' indicates a possible typo or the use of visually similar Unicode characters (e.g., Cyrillic 'е' instead of Latin 'e') in the variable name, leading to the variable being unrecognized.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-12T12:18:06.395Z","next_check":"2026-06-25T00:00:00.000Z","problems":[{"fix":"Ensure that the string passed to the IDNA encoding function represents a valid hostname, not an entire URL, and that each domain label (segment between dots) is no longer than 63 bytes. For URLs, parse out the hostname component before applying IDNA encoding.","cause":"This error often occurs when a hostname or part of a URL being processed for Internationalized Domain Names (IDNA) violates DNS specifications, such as a label exceeding the maximum length of 63 bytes or containing characters not allowed in domain names.","error":"UnicodeError: encoding with 'idna' codec failed (UnicodeError: label empty or too long)"},{"fix":"To ensure the `idna` codec is loaded, explicitly import `encodings.idna` (or `import idna` if using the external library) at the application's startup, or perform a no-op encoding/decoding operation like `b''.decode('idna')` or `u''.encode('idna')` early in your code.","cause":"This error typically indicates that the 'idna' codec is not properly registered or available in the Python environment, which can happen with embedded Python distributions or when `encodings.idna` isn't implicitly loaded, particularly in multi-threaded applications.","error":"LookupError: unknown encoding: idna"},{"fix":"Validate the input domain name string against IDNA 2008 and UTS #46 rules, ensuring it adheres to character sets, contextual requirements, and structural rules. Use specific exception handling for subclasses like `idna.InvalidCodepoint` to identify and address the exact violation.","cause":"This is the base exception for various issues where a domain name string violates the IDNA 2008 or Unicode IDNA Compatibility Processing (UTS #46) specifications, encompassing problems like disallowed characters, incorrect bidirectional text rules (IDNABidiError), or invalid character contexts (InvalidCodepointContext).","error":"idna.IDNAError"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"install_tag":"verified","quickstart_score":0,"quickstart_tag":"stale","pypi_latest":null,"install_checks":{"last_tested":"2026-05-12","tag":"verified","tag_description":"installs cleanly on critical runtimes, fast import, recently tested","results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.3,"disk_size":"18.5M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.3,"disk_size":"19M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.4,"disk_size":"20.2M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.4,"disk_size":"21M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.4,"disk_size":"12.1M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.4,"disk_size":"13M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.04,"mem_mb":1.6,"disk_size":"11.8M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.03,"mem_mb":1.4,"disk_size":"12M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.02,"mem_mb":1.2,"disk_size":"17.8M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"default","exit_code":0,"wheel_type":null,"failure_reason":null,"install_time_s":null,"import_time_s":0.01,"mem_mb":1.2,"disk_size":"18M"}]},"quickstart_checks":{"last_tested":"2026-04-23","tag":"stale","tag_description":"widespread failures or data too old to trust","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]}}