encode/httpx · error · TooManyRedirects

Exceeded maximum allowed redirects.

Error message

Exceeded maximum allowed redirects.

What it means

Raised as httpx.TooManyRedirects by _send_handling_redirects when len(history) exceeds self.max_redirects (default 20). Each followed 3xx appends to history; once over the cap the redirect chain is aborted.

Source

Thrown at httpx/_client.py:972

                    response.read()
                    request = next_request
                    history.append(response)

                except BaseException as exc:
                    response.close()
                    raise exc
        finally:
            auth_flow.close()

    def _send_handling_redirects(
        self,
        request: Request,
        follow_redirects: bool,
        history: list[Response],
    ) -> Response:
        while True:
            if len(history) > self.max_redirects:
                raise TooManyRedirects(
                    "Exceeded maximum allowed redirects.", request=request
                )

            for hook in self._event_hooks["request"]:
                hook(request)

            response = self._send_single_request(request)
            try:
                for hook in self._event_hooks["response"]:
                    hook(response)
                response.history = list(history)

                if not response.has_redirect_location:
                    return response

                request = self._build_redirect_request(request, response)
                history = history + [response]

View on GitHub (pinned to b5addb64f0)

Solutions

  1. Raise the cap: httpx.Client(max_redirects=50).
  2. Set follow_redirects=False and follow the final Location yourself once.
  3. Inspect the caught exception's .request/.history to find where the loop starts and fix the server.

Example fix

// before
client.get(url, follow_redirects=True)  # TooManyRedirects
// after
httpx.get(url, follow_redirects=True, max_redirects=50)
Defensive patterns

Strategy: retry

Validate before calling

import httpx
# validate the redirect cap you intend to use
assert isinstance(max_redirects, int) and max_redirects > 0
client = httpx.Client(follow_redirects=True, max_redirects=max_redirects)

Try / catch

try:
    resp = client.get(url, follow_redirects=True)
except httpx.TooManyRedirects as exc:
    # inspect exc.history to find the loop, then fetch the resolved URL directly
    last = exc.history[-1]
    resp = client.get(last.headers.get("Location", url), follow_redirects=False)

Prevention

When it happens

Trigger: A request with follow_redirects=True that enters a redirect loop (A->B->A) or a chain longer than max_redirects (default DEFAULT_MAX_REDIRECTS=20).

Common situations: Redirect loops caused by http<->https or trailing-slash ping-pong; misconfigured servers; legitimate but very long redirect chains.

Related errors


AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04). Data as JSON: /data/errors/7305bb3382f5a59c.json. Report an issue: GitHub.