{"record":{"id":"42f4d69a27259712","repo":"Hmbown/CodeWhale","slug":"mcp-http-redirect-would-downgrade-https","errorCode":null,"errorMessage":"MCP HTTP redirect would downgrade HTTPS","messagePattern":"MCP HTTP redirect would downgrade HTTPS","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp/http_client.rs","lineNumber":134,"sourceCode":"            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);\n            }\n            if next_url.origin() != url.origin() {\n                // Custom headers can contain credentials under arbitrary names;\n                // retaining just Authorization/ Cookie exclusions is insufficient.\n                let mut headers = header::HeaderMap::new();\n                for name in [header::ACCEPT, header::CONTENT_TYPE] {\n                    if let Some(value) = request.headers().get(&name) {\n                        headers.insert(name, value.clone());","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp/http_client.rs#L116-L152","documentation":"A redirect from an https:// MCP endpoint to a non-https target (http:, or another scheme) is rejected. Downgrading transport security mid-redirect would expose MCP traffic and headers to interception, so the client refuses to follow.","triggerScenarios":"execute_inner processes a redirect where the current URL scheme is https but the joined next_url scheme is not https — e.g. Location: http://example.com/mcp.","commonSituations":"Reverse proxy emitting absolute http:// Location headers behind TLS termination; misconfigured X-Forwarded-Proto so the app generates http redirect URLs; server redirecting to a plain-HTTP health/login endpoint.","solutions":["Fix the server/proxy to emit https:// redirect targets (set X-Forwarded-Proto correctly, use relative Locations)","Point the client directly at the final https URL, skipping the redirect chain","If the target genuinely only supports http, configure the client against an explicit http:// endpoint at the operator level (accepting the security implications)"],"exampleFix":"// before (server config)\nreturn redirect(\"http://example.com/mcp\");\n// after\nreturn redirect(\"https://example.com/mcp\"); // or relative \"/mcp\"","handlingStrategy":"validation","validationCode":"let u = Url::parse(endpoint)?;\nif u.scheme() != \"https\" {\n    // decide up front: use https endpoint or explicitly configure http\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = client.execute(req).await {\n    if e.to_string().contains(\"would downgrade HTTPS\") {\n        // fix proxy X-Forwarded-Proto / Location scheme server-side\n    }\n}","preventionTips":["Set X-Forwarded-Proto correctly on TLS-terminating proxies","Prefer relative Location headers in server redirects","Only ever configure https:// MCP endpoints"],"tags":["mcp","http","redirect","tls","security"],"backgroundTag":"invalid-url","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T21:17:16.096Z"}