{"record":{"id":"ec35c6dca361c091","repo":"Hmbown/CodeWhale","slug":"mcp-http-redirect-limit-exceeded","errorCode":null,"errorMessage":"MCP HTTP redirect limit exceeded","messagePattern":"MCP HTTP redirect limit exceeded","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp/http_client.rs","lineNumber":126,"sourceCode":"        for redirect_count in 0..=5 {\n            let url = request.url().clone();\n            let client = self.client_for_target(&url).await?;\n            // MCP and OAuth requests have buffered bodies. Keep the exact request\n            // to replay only after the Location has passed the same guard.\n            let next_request = request\n                .try_clone()\n                .context(\"MCP request body cannot be replayed\")?;\n            let response = client.execute(request).await?;\n            if !follow_redirects\n                || !matches!(response.status().as_u16(), 301 | 302 | 303 | 307 | 308)\n            {\n                return Ok(response);\n            }\n            let Some(location) = response.headers().get(header::LOCATION) else {\n                return Ok(response);\n            };\n            if redirect_count == 5 {\n                bail!(\"MCP HTTP redirect limit exceeded\");\n            }\n            let next_url = url.join(location.to_str().context(\"invalid MCP redirect Location\")?)?;\n            validate_url(&next_url)?;\n            if url_has_credentials(&next_url) {\n                bail!(\"MCP HTTP redirect must not contain credentials\");\n            }\n            if url.scheme() == \"https\" && next_url.scheme() != \"https\" {\n                bail!(\"MCP HTTP redirect would downgrade HTTPS\");\n            }\n            request = next_request;\n            if (matches!(response.status().as_u16(), 301 | 302) && request.method() == Method::POST)\n                || (response.status().as_u16() == 303 && request.method() != Method::HEAD)\n            {\n                *request.method_mut() = Method::GET;\n                *request.body_mut() = None;\n                request.headers_mut().remove(header::CONTENT_TYPE);\n                request.headers_mut().remove(header::CONTENT_LENGTH);\n                request.headers_mut().remove(header::TRANSFER_ENCODING);","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp/http_client.rs#L108-L144","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)"],"exampleFix":"// before\nlet client = client_for_target(...); // keeps following redirects until bail\n// after\n// resolve the redirect chain out-of-band and use the final URL directly\nlet final_url = resolve_redirects(&url).await?; // separate tooling\nlet client = McpHttpClient::new(final_url.as_str(), ...)?;","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match client.execute(request).await {\n    Err(e) if e.to_string().contains(\"redirect limit exceeded\") => {\n        // diagnose server redirect loop; optionally resolve final URL manually\n    }\n    other => other?,\n}","preventionTips":["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"],"tags":["mcp","http","redirect","limits"],"backgroundTag":"http-request-failed","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T16:17:23.217Z"}