{"id":"75dd8c8b76a71165","repo":"encode/httpx","slug":"error-type-0-status-code-0-reason-phrase-f","errorCode":null,"errorMessage":"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\nRedirect location: '{0.headers[location]}'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}","messagePattern":"(.+?) '(.+?) (.+?)' for url '(.+?)'\nRedirect location: '(.+?)'\nFor more information check: https://developer\\.mozilla\\.org/en-US/docs/Web/HTTP/Status/(.+?)","errorType":"http","errorClass":"HTTPStatusError","httpStatus":null,"severity":"error","filePath":"httpx/_models.py","lineNumber":829,"sourceCode":"                \"Redirect location: '{0.headers[location]}'\\n\"\n                \"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}\"\n            )\n        else:\n            message = (\n                \"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\\n\"\n                \"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}\"\n            )\n\n        status_class = self.status_code // 100\n        error_types = {\n            1: \"Informational response\",\n            3: \"Redirect response\",\n            4: \"Client error\",\n            5: \"Server error\",\n        }\n        error_type = error_types.get(status_class, \"Invalid status code\")\n        message = message.format(self, error_type=error_type)\n        raise HTTPStatusError(message, request=request, response=self)\n\n    def json(self, **kwargs: typing.Any) -> typing.Any:\n        return jsonlib.loads(self.content, **kwargs)\n\n    @property\n    def cookies(self) -> Cookies:\n        if not hasattr(self, \"_cookies\"):\n            self._cookies = Cookies()\n            self._cookies.extract_cookies(self)\n        return self._cookies\n\n    @property\n    def links(self) -> dict[str | None, dict[str, str]]:\n        \"\"\"\n        Returns the parsed header links of the response, if any\n        \"\"\"\n        header = self.headers.get(\"link\")\n        if header is None:","sourceCodeStart":811,"sourceCodeEnd":847,"githubUrl":"https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L811-L847","documentation":"The message format used by `raise_for_status` when the response has a redirect location (3xx with a `Location` header, as defined by `has_redirect_location`). It raises `HTTPStatusError` with the status code, reason, URL, and the redirect target, linking the MDN status reference. This is the 'redirect' variant of the two message branches in `raise_for_status`.","triggerScenarios":"Calling `response.raise_for_status()` on a 301/302/303/307/308 response whose `Location` header is present and `is_success` is False — typically because redirects were disabled (`follow_redirects=False`) or the redirect chain was halted.","commonSituations":"Passing `follow_redirects=False` to inspect a redirect manually; SSO/OAuth flows where you intentionally stop at the 302; debugging a redirect loop.","solutions":["Enable `follow_redirects=True` on the client or per-request if you want httpx to follow automatically.","Inspect `response.headers['Location']` and `response.is_redirect` before calling `raise_for_status()` to handle redirects yourself.","Wrap in `try/except httpx.HTTPStatusError as e:` and read `e.response.status_code` / `e.response.headers['Location']`.","Verify the redirect target is the expected host to avoid open-redirect surprises."],"exampleFix":"// before\nr = client.get(url, follow_redirects=False)\nr.raise_for_status()  # HTTPStatusError on 302\n\n// after\nr = client.get(url, follow_redirects=True)\nr.raise_for_status()","handlingStrategy":"try-catch","validationCode":"if response.is_redirect and not response.is_success:\n    # handle redirect manually instead of raise_for_status()\n    loc = response.headers.get('Location')","typeGuard":"import httpx\n\ndef is_unfollowed_redirect(resp: httpx.Response) -> bool:\n    return resp.has_redirect_location and not resp.is_success","tryCatchPattern":"try:\n    response.raise_for_status()\nexcept httpx.HTTPStatusError as e:\n    if e.response.has_redirect_location:\n        next_url = e.response.headers['Location']\n        # follow manually or surface to caller\n    else:\n        raise","preventionTips":["Set follow_redirects=True unless you intentionally inspect 3xx.","Check response.is_redirect before calling raise_for_status().","Validate the Location host against an allowlist to avoid open redirects."],"tags":["http-status","redirect","raise-for-status","http-status-error"],"analyzedSha":"b5addb64f0161ff6bfe94c124ef76f6a1fba5254","analyzedAt":"2026-08-04T19:32:56.768Z","schemaVersion":2}