Hmbown/CodeWhale · error
MCP HTTP redirect limit exceeded
Error message
MCP HTTP redirect limit exceeded
What it means
The MCP HTTP client follows redirects manually and caps them at 5. When a server (or redirect chain) exceeds six hops, execute_inner stops and throws this error rather than looping indefinitely. It protects against redirect loops and infinite chains.
Solutions
- Fix the server/proxy redirect chain so the endpoint responds within 5 hops
- Connect directly to the final destination URL instead of following a chain
- Check for scheme or trailing-slash loops in reverse-proxy config (common: HTTP->HTTPS loop with HSTS off)
Example fix
// before let client = client_for_target(...); // keeps following redirects until bail // after // resolve the redirect chain out-of-band and use the final URL directly let final_url = resolve_redirects(&url).await?; // separate tooling let client = McpHttpClient::new(final_url.as_str(), ...)?;
Defensive patterns
Strategy: try-catch
Try / catch
match client.execute(request).await {
Err(e) if e.to_string().contains("redirect limit exceeded") => {
// diagnose server redirect loop; optionally resolve final URL manually
}
other => other?,
} Prevention
- Curl -IL the endpoint before configuring it to verify a short redirect chain
- Check reverse-proxy rules for redirect loops (scheme, trailing slash, hostname)
- Point the client directly at the final destination to skip redirects entirely
When it happens
Trigger: execute_inner receives a 3xx response with a Location header when redirect_count already equals 5 — i.e. the sixth redirect in one request chain.
Common situations: Server misconfiguration causing a redirect loop (e.g. http->https->http, or trailing-slash loops); an auth gateway bouncing between login endpoints; a proxy that rewrites redirects endlessly.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- MCP HTTP discovered URL must not contain credentials
- MCP HTTP redirect must not contain credentials
- MCP HTTP redirect would downgrade HTTPS
- MCP redirect leaves the reviewed plugin origin
- bundle redirect is missing a valid Location header
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/ec35c6dca361c091.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/mcp/http_client.rs:126
for redirect_count in 0..=5 {
let url = request.url().clone();
let client = self.client_for_target(&url).await?;
// MCP and OAuth requests have buffered bodies. Keep the exact request
// to replay only after the Location has passed the same guard.
let next_request = request
.try_clone()
.context("MCP request body cannot be replayed")?;
let response = client.execute(request).await?;
if !follow_redirects
|| !matches!(response.status().as_u16(), 301 | 302 | 303 | 307 | 308)
{
return Ok(response);
}
let Some(location) = response.headers().get(header::LOCATION) else {
return Ok(response);
};
if redirect_count == 5 {
bail!("MCP HTTP redirect limit exceeded");
}
let next_url = url.join(location.to_str().context("invalid MCP redirect Location")?)?;
validate_url(&next_url)?;
if url_has_credentials(&next_url) {
bail!("MCP HTTP redirect must not contain credentials");
}
if url.scheme() == "https" && next_url.scheme() != "https" {
bail!("MCP HTTP redirect would downgrade HTTPS");
}
request = next_request;
if (matches!(response.status().as_u16(), 301 | 302) && request.method() == Method::POST)
|| (response.status().as_u16() == 303 && request.method() != Method::HEAD)
{
*request.method_mut() = Method::GET;
*request.body_mut() = None;
request.headers_mut().remove(header::CONTENT_TYPE);
request.headers_mut().remove(header::CONTENT_LENGTH);
request.headers_mut().remove(header::TRANSFER_ENCODING);View on GitHub (pinned to 73e0f67d83)