seanmonstar/reqwest · error · reqwest::Error
error following redirect
Error message
error following redirect
What it means
The `Kind::Redirect` error from `error::redirect(...)` (error.rs:364-366). It fires when the redirect policy itself errors — most often because the redirect `Location` has a disallowed scheme, the redirect chain exceeds the limit (default 10), or a redirect loop is detected.
Source
Thrown at src/error.rs:365
pub(crate) fn body<E: Into<BoxError>>(e: E) -> Error {
Error::new(Kind::Body, Some(e))
}
pub(crate) fn decode<E: Into<BoxError>>(e: E) -> Error {
Error::new(Kind::Decode, Some(e))
}
pub(crate) fn request<E: Into<BoxError>>(e: E) -> Error {
Error::new(Kind::Request, Some(e))
}
pub(crate) fn dns<E: Into<BoxError>>(e: E) -> BoxError {
Box::new(DnsError { inner: e.into() })
}
pub(crate) fn redirect<E: Into<BoxError>>(e: E, url: Url) -> Error {
Error::new(Kind::Redirect, Some(e)).with_url(url)
}
pub(crate) fn status_code(
url: Url,
status: StatusCode,
#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))] reason: Option<hyper::ext::ReasonPhrase>,
) -> Error {
Error::new(
Kind::Status(
status,
#[cfg(not(all(
target_arch = "wasm32",
any(target_os = "unknown", target_os = "none")
)))]
reason,
),
None::<Error>,
)View on GitHub (pinned to 17e9bcb51c)
Solutions
- Inspect `e.url()` to see where the redirect chain stopped.
- Raise the limit via `Client::builder().redirect(Policy::limited(20))` if the chain is legitimately long.
- If the issue is an https→http downgrade, decide explicitly: allow it with `Policy::default()` or keep https-only and fail.
- For custom policies, return `Policy::stop()` instead of `Policy::error(...)` to keep the last response rather than erroring.
Example fix
// before
let client = Client::builder().build()?; // default limit 10
let r = client.get(url).send().await?; // 'error following redirect' on long chain
// after
let client = Client::builder()
.redirect(reqwest::redirect::Policy::limited(30))
.build()?;
let r = client.get(url).send().await?; Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate redirect tolerance for known chains.
let client = Client::builder()
.redirect(reqwest::redirect::Policy::limited(max_hops_for(url)))
.build()?;
Type guard
fn is_redirect_error(e: &reqwest::Error) -> bool { e.is_redirect() }
Try / catch
let resp = match client.get(&url).send().await {
Ok(r) => r,
Err(e) if e.is_redirect() => {
log::warn!("redirect stopped at {:?}", e.url());
return Err(e.into());
}
Err(e) => return Err(e.into()),
}; Prevention
- Tune redirect::Policy::limit to the longest legitimate chain.
- For https-only clients, expect https→http downgrades to error; decide intentionally.
- Return Policy::stop() from custom policies when you want to keep the last response.
When it happens
Trigger: A `Location` response header pointing to a non-http(s) scheme on an https-only client (redirect.rs:325-328 wraps `url_bad_scheme`); more than `redirect(Policy::limit(n))` hops; a self-referential redirect loop; a custom `RedirectPolicy` returning `Policy::error(...)`.
Common situations: Site redirects from https to http while the client is https-only; infinitely redirecting auth flow; CDN redirect chain deeper than the default 10; custom policy enforcing allow-lists that rejects a target.
Related errors
- error sending request
- HTTP/3 only supports 'https' or 'h3' schemes, got: {}
- error sending request
- builder error
- request or response body error
AI-assisted analysis of seanmonstar/reqwest@17e9bcb51c (2026-08-06).
Data as JSON: /data/errors/31054cf682b5045e.json.
Report an issue: GitHub.