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

  1. Set `allow_redirects=False` and handle the Location header yourself (validate/normalize before re-requesting).
  2. Fix the server's redirect target — aiohttp is correctly refusing a malformed URL.
  3. 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

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


AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04). Data as JSON: /data/errors/6cf422060ac3f4c0.json. Report an issue: GitHub.