aio-libs/aiohttp · error · InvalidUrlRedirectClientError
Server attempted redirecting to a location that does not loo
Error message
Server attempted redirecting to a location that does not look like a URL
What it means
Raised as `InvalidUrlRedirectClientError` (client.py:808-819) when the `Location` (or `URI`) header from a 3xx response cannot be parsed by yarl's `URL(...)` constructor. The exception chains from the underlying `ValueError`. This is distinct from a non-http scheme redirect (which raises `NonHttpUrlRedirectClientError`) — this one means the value isn't even URL-shaped.
Source
Thrown at aiohttp/client.py:816
hdrs.URI
)
if r_url is None:
# see github.com/aio-libs/aiohttp/issues/2022
break
else:
# reading from correct redirection
# response is forbidden
resp.release()
try:
parsed_redirect_url = URL(
r_url, encoded=not self._requote_redirect_url
)
except ValueError as e:
if req._body is not None:
await req._body.close()
resp.close()
raise InvalidUrlRedirectClientError(
r_url,
"Server attempted redirecting to a location that does not look like a URL",
) from e
scheme = parsed_redirect_url.scheme
if scheme not in HTTP_AND_EMPTY_SCHEMA_SET:
if req._body is not None:
await req._body.close()
resp.close()
raise NonHttpUrlRedirectClientError(r_url)
elif not scheme:
parsed_redirect_url = url.join(parsed_redirect_url)
try:
redirect_origin = parsed_redirect_url.origin()
except ValueError as origin_val_err:
if req._body is not None:
await req._body.close()View on GitHub (pinned to c0ef574e29)
Solutions
- Set `allow_redirects=False` and handle the Location header yourself (validate/normalize before re-requesting).
- Fix the server's redirect target — aiohttp is correctly refusing a malformed URL.
- If the server returns an unquoted URL, try `ClientSession(requote_redirect_url=False)` to skip requoting (note: still must be parseable).
Example fix
// before
resp = await session.get(url) # server Location is malformed -> raise
// after
resp = await session.get(url, allow_redirects=False)
loc = resp.headers.get('Location')
if loc and valid_url(loc):
resp = await session.get(session._build_url(loc)) Defensive patterns
Strategy: validation
Validate before calling
from yarl import URL
def valid_redirect_target(loc: str) -> bool:
try:
URL(loc)
return True
except ValueError:
return False Try / catch
from aiohttp import InvalidUrlRedirectClientError
try:
resp = await session.get(url)
except InvalidUrlRedirectClientError as e:
# fall back to manual handling with allow_redirects=False
resp = await session.get(url, allow_redirects=False) Prevention
- Use allow_redirects=False against servers you don't control.
- Validate the Location header yourself before following.
- Log upstream redirect targets to catch server misconfigurations early.
When it happens
Trigger: Server returns `Location: <<<garbage>>>`, a `Location` with illegal characters, an empty/malformed URI template, or binary content in the header. The `encoded=` flag depends on `requote_redirect_url`.
Common situations: Misconfigured server returning a templated Location without substitution; upstream proxy rewriting the header; clients hitting a dev/staging server with broken redirect logic; reverse proxies that prepend a bad prefix.
Related errors
- Invalid redirect URL origin
- base_url must have a trailing '/'
- Cannot combine AUTHORIZATION header with credentials encoded
- Cannot follow redirect with a consumed request body. Use byt
- Invalid response status
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/6cf422060ac3f4c0.json.
Report an issue: GitHub.