{"id":"3ff3be6e08ec3d99","repo":"psf/requests","slug":"url-has-an-invalid-label","errorCode":null,"errorMessage":"URL has an invalid label.","messagePattern":"URL has an invalid label\\.","errorType":"exception","errorClass":"InvalidURL","httpStatus":null,"severity":"error","filePath":"src/requests/models.py","lineNumber":532,"sourceCode":"\n        if not scheme:\n            raise MissingSchema(\n                f\"Invalid URL {url!r}: No scheme supplied. \"\n                f\"Perhaps you meant https://{url}?\"\n            )\n\n        if not host:\n            raise InvalidURL(f\"Invalid URL {url!r}: No host supplied\")\n\n        # In general, we want to try IDNA encoding the hostname if the string contains\n        # non-ASCII characters. This allows users to automatically get the correct IDNA\n        # behaviour. For strings containing only ASCII characters, we need to also verify\n        # it doesn't start with a wildcard (*), before allowing the unencoded hostname.\n        if not unicode_is_ascii(host):\n            try:\n                host = self._get_idna_encoded_host(host)\n            except UnicodeError:\n                raise InvalidURL(\"URL has an invalid label.\")\n        elif host.startswith((\"*\", \".\")):\n            raise InvalidURL(\"URL has an invalid label.\")\n\n        # Carefully reconstruct the network location\n        netloc = auth or \"\"\n        if netloc:\n            netloc += \"@\"\n        netloc += host\n        if port:\n            netloc += f\":{port}\"\n\n        # Bare domains aren't valid URLs.\n        if not path:\n            path = \"/\"\n\n        if isinstance(params, (str, bytes)):\n            params = to_native_string(params)\n","sourceCodeStart":514,"sourceCodeEnd":550,"githubUrl":"https://github.com/psf/requests/blob/414f0513c33883adf6f2b46901d4f0b38a455851/src/requests/models.py#L514-L550","documentation":"An `InvalidURL` raised in `prepare_url` when the hostname contains non-ASCII characters and IDNA encoding fails. Requests attempts to convert internationalized domain names to punycode via `_get_idna_encoded_host`; if the idna library raises (label too long, empty label, disallowed code points), the host cannot form a valid DNS name and the URL is rejected.","triggerScenarios":"Requesting a URL whose host has a non-ASCII label that violates IDNA rules — e.g. a label over 63 characters, an empty label ('http://exämple..com'), disallowed characters or misplaced combining marks. Only reached when `unicode_is_ascii(host)` is False (src/requests/models.py:528).","commonSituations":"URLs scraped from web pages or user input containing lookalike/unicode characters; invisible characters (zero-width space, non-breaking space) pasted into a hostname from a document or chat; malformed internationalized domains in datasets.","solutions":["Inspect the hostname bytes: `print(ascii(urlparse(url).hostname))` to reveal hidden unicode characters, then strip or fix them.","Sanitize input URLs (strip whitespace and zero-width/invisible characters) before requesting.","If the domain is genuinely internationalized, pre-encode it yourself with `idna.encode(host)` to get a specific error explaining which label is invalid."],"exampleFix":"# before (host contains a zero-width space)\nrequests.get('https://exam\\u200bple.com')\n\n# after\nurl = raw_url.replace('\\u200b', '').strip()\nrequests.get(url)","handlingStrategy":"validation","validationCode":"from urllib.parse import urlparse\nhost = urlparse(url).hostname or \"\"\n# each DNS label must be 1-63 chars\nif not all(0 < len(label) <= 63 for label in host.split(\".\")):\n    raise ValueError(f\"invalid hostname in {url!r}\")\nhost.encode(\"idna\")  # raises UnicodeError for invalid IDNA labels","typeGuard":null,"tryCatchPattern":"from requests.exceptions import InvalidURL\ntry:\n    resp = requests.get(url)\nexcept InvalidURL as e:\n    if \"invalid label\" in str(e).lower():\n        ...  # non-ASCII host failed IDNA encoding\n    raise","preventionTips":["Pre-encode internationalized hostnames with hostname.encode('idna') to surface bad labels early","Reject hostnames with empty labels (leading/trailing/double dots) or labels over 63 chars","Sanitize user-entered hostnames before building URLs"],"tags":["python","requests","url","idna","unicode","validation"],"analyzedSha":"414f0513c33883adf6f2b46901d4f0b38a455851","analyzedAt":"2026-07-31T19:24:57.696Z","schemaVersion":2}