{"id":"74c5144abf08e4d0","repo":"aio-libs/aiohttp","slug":"path","errorCode":null,"errorMessage":"{path}","messagePattern":"\\{path\\}","errorType":"http","errorClass":"InvalidURLError","httpStatus":400,"severity":"error","filePath":"aiohttp/http_parser.py","lineNumber":702,"sourceCode":"            # NOTE: HTTP Request-Line input producing different\n            # NOTE: `yarl.URL()` objects\n            url = URL.build(\n                path=path_part,\n                query_string=qs_part,\n                fragment=url_fragment,\n                encoded=True,\n            )\n        elif path == \"*\" and method == \"OPTIONS\":\n            # asterisk-form,\n            url = URL(path, encoded=True)\n        else:\n            # absolute-form for proxy maybe,\n            # https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.2\n            url = URL(path, encoded=True)\n            if not url.absolute:\n                # authority-form is only allowed with CONNECT\n                # https://www.rfc-editor.org/info/rfc9112/#section-3.2.3-1\n                raise InvalidURLError(\n                    path.encode(errors=\"surrogateescape\").decode(\"latin1\")\n                )\n\n        # read headers\n        (\n            headers,\n            raw_headers,\n            close,\n            compression,\n            upgrade,\n            chunked,\n        ) = self.parse_headers(lines[1:])\n\n        if version_o == HttpVersion11 and hdrs.HOST not in headers:\n            raise BadHttpMessage(\"Missing 'Host' header in request.\")\n\n        if close is None:  # then the headers weren't set in the request\n            if version_o <= HttpVersion10:  # HTTP 1.0 must asks to not close","sourceCodeStart":684,"sourceCodeEnd":720,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/c0ef574e29109210e96e652771ae4e7b88615fa4/aiohttp/http_parser.py#L684-L720","documentation":"Raised by HttpRequestParser.parse_message (aiohttp/http_parser.py:702) when the request-target does not match any allowed form (RFC 9112 section 3.2). If it does not start with '/' (origin-form), is not '*' with OPTIONS (asterisk-form), and yarl cannot parse it as an absolute URL (absolute-form for proxies), AND the method is not CONNECT (authority-form), InvalidURLError(path) is raised. Authority-form (host:port) is ONLY valid with CONNECT.","triggerScenarios":"A request like 'GET example.com:80 HTTP/1.1' (authority-form with a non-CONNECT method), 'OPTIONS foo HTTP/1.1' (asterisk-form requires a literal '*'), or a malformed target that is neither a path nor a valid absolute URL. Common when a client confuses proxy-style absolute URIs with origin-form paths.","commonSituations":"Proxies receiving absolute-form for non-proxy requests, clients sending authority-form by mistake, raw clients with the wrong path syntax, or HTTP/2 pseudo-headers leaking into HTTP/1.1.","solutions":["Use origin-form ('/path?query') for normal requests to an origin server.","Use the literal '*' only with OPTIONS; use authority-form ('host:port') only with CONNECT.","Use absolute-form ('http://host/path') only for forward-proxy requests.","Let aiohttp's ClientSession format the request target from the URL you pass it."],"exampleFix":"# before - authority-form with GET (invalid)\nsock.send(b'GET example.com:80 HTTP/1.1\\r\\n\\r\\n')\n# after - origin-form + Host header (normal origin request)\nsock.send(b'GET / HTTP/1.1\\r\\nHost: example.com\\r\\n\\r\\n')\n# or, for CONNECT, authority-form is correct:\nsock.send(b'CONNECT example.com:80 HTTP/1.1\\r\\nHost: example.com:80\\r\\n\\r\\n')","handlingStrategy":"validation","validationCode":"def valid_request_target(method: str, target: str) -> bool:\n    from yarl import URL\n    if target.startswith('/'):           # origin-form\n        return True\n    if target == '*' and method == 'OPTIONS':   # asterisk-form\n        return True\n    if method == 'CONNECT' and ':' in target:    # authority-form\n        return True\n    try:\n        return URL(target, encoded=True).absolute  # absolute-form\n    except Exception:\n        return False\nassert valid_request_target(method, target)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use origin-form (/path) for regular requests","Reserve CONNECT for authority-form and OPTIONS for the literal '*'","Let ClientSession format the target from a yarl URL"],"tags":["http","url","parser","request-line","validation"],"analyzedSha":"c0ef574e29109210e96e652771ae4e7b88615fa4","analyzedAt":"2026-08-04T19:51:05.467Z","schemaVersion":2}