encode/httpx · error · HTTPStatusError
{error_type} '{0.status_code} {0.reason_phrase}' for url '{0
Error message
{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code} What it means
The non-redirect message format used by `raise_for_status` for any non-success response without a redirect location (4xx, 5xx, or other). It raises `HTTPStatusError` with status code, reason phrase, URL, and an MDN docs link. The `error_type` prefix is chosen from the status class ('Client error', 'Server error', 'Redirect response', 'Informational response').
Source
Thrown at httpx/_models.py:829
"Redirect location: '{0.headers[location]}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
else:
message = (
"{error_type} '{0.status_code} {0.reason_phrase}' for url '{0.url}'\n"
"For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/{0.status_code}"
)
status_class = self.status_code // 100
error_types = {
1: "Informational response",
3: "Redirect response",
4: "Client error",
5: "Server error",
}
error_type = error_types.get(status_class, "Invalid status code")
message = message.format(self, error_type=error_type)
raise HTTPStatusError(message, request=request, response=self)
def json(self, **kwargs: typing.Any) -> typing.Any:
return jsonlib.loads(self.content, **kwargs)
@property
def cookies(self) -> Cookies:
if not hasattr(self, "_cookies"):
self._cookies = Cookies()
self._cookies.extract_cookies(self)
return self._cookies
@property
def links(self) -> dict[str | None, dict[str, str]]:
"""
Returns the parsed header links of the response, if any
"""
header = self.headers.get("link")
if header is None:View on GitHub (pinned to b5addb64f0)
Solutions
- Wrap the call: `try: r.raise_for_status() except httpx.HTTPStatusError as e: ...` and branch on `e.response.status_code`.
- Add retries with backoff for 5xx (and 429) only — do NOT blind-retry 4xx.
- For auth flows, refresh the token on 401 before retrying once.
- Log `e.response.text` / `e.response.json()` for diagnostics but avoid leaking it to end users.
Example fix
// before
r = client.get(url)
r.raise_for_status() # raises on 404, unhandled
// after
try:
r = client.get(url)
r.raise_for_status()
except httpx.HTTPStatusError as e:
if e.response.status_code == 404:
return None
raise Defensive patterns
Strategy: try-catch
Validate before calling
if not response.is_success:
status = response.status_code
# branch on 4xx vs 5xx before raise_for_status() Type guard
import httpx
def is_http_error(resp: httpx.Response) -> bool:
return resp.status_code >= 400 Try / catch
try:
response.raise_for_status()
except httpx.HTTPStatusError as e:
code = e.response.status_code
if code == 404:
return None
if code == 429:
backoff_and_retry()
if 500 <= code < 600:
retry_with_backoff()
raise Prevention
- httpx never raises on 4xx/5xx automatically - always call raise_for_status() or check status explicitly.
- Branch on status code; do not blind-retry 4xx.
- Refresh auth tokens on 401 before a single retry.
When it happens
Trigger: Calling `response.raise_for_status()` after the server returned 4xx (e.g. 401, 404, 422) or 5xx (500, 502, 503).
Common situations: Forgetting that httpx does NOT raise on 4xx/5xx by default (unlike `requests.raise_for_status()` patterns); missing/expired auth tokens producing 401; upstream outages returning 502/503.
Related errors
- {error_type} '{0.status_code} {0.reason_phrase}' for url '{0
- {exc}
- Cannot call `raise_for_status` as the request instance has n
AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04).
Data as JSON: /data/errors/db33fc534670e66f.json.
Report an issue: GitHub.