{"record":{"id":"ccd82752a155f63e","repo":"openai/codex","slug":"mcp-http-headers-helper-returned-a-reserved-header","errorCode":null,"errorMessage":"MCP HTTP headers helper returned a reserved header","messagePattern":"MCP HTTP headers helper returned a reserved header","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"codex-rs/rmcp-client/src/http_headers.rs","lineNumber":391,"sourceCode":"                | \"authorization\"\n                | \"connection\"\n                | \"content-encoding\"\n                | \"content-length\"\n                | \"content-type\"\n                | \"host\"\n                | \"keep-alive\"\n                | \"last-event-id\"\n                | \"mcp-protocol-version\"\n                | \"mcp-session-id\"\n                | \"origin\"\n                | \"proxy-connection\"\n                | \"referer\"\n                | \"te\"\n                | \"trailer\"\n                | \"transfer-encoding\"\n                | \"upgrade\"\n        ) {\n            return Err(anyhow!(\n                \"MCP HTTP headers helper returned a reserved header\"\n            ));\n        }\n        if parsed.contains_key(&name) {\n            return Err(anyhow!(\n                \"MCP HTTP headers helper returned duplicate header names\"\n            ));\n        }\n        let value = HeaderValue::from_str(&value)\n            .map_err(|_| anyhow!(\"MCP HTTP headers helper returned an invalid header value\"))?;\n        parsed.insert(name, value);\n    }\n    Ok(parsed)\n}\n\n#[cfg(test)]\n#[path = \"http_headers_tests.rs\"]\nmod tests;","sourceCodeStart":373,"sourceCodeEnd":409,"githubUrl":"https://github.com/openai/codex/blob/339751715c64496cb86246bfb3935f40e309dd3d/codex-rs/rmcp-client/src/http_headers.rs#L373-L409","documentation":"The helper may not supply headers the adapter owns: accept, authorization, connection, content-encoding, content-length, content-type, host, keep-alive, last-event-id, mcp-protocol-version, mcp-session-id, origin, proxy-connection, referer, te, trailer, transfer-encoding, upgrade. Protocol framing and auth (bearer/OAuth) are managed by the client itself, so helper-supplied values for these names are rejected outright to avoid spoofing or corrupting protocol state.","triggerScenarios":"Helper JSON including Authorization (owned by bearer/OAuth), Accept or Content-Type (set per MCP request), Mcp-Session-Id / Mcp-Protocol-Version, or hop-by-hop headers like Connection, Transfer-Encoding, Upgrade.","commonSituations":"Credential helpers that naturally want to set Authorization; helpers forwarding a captured browser request's headers wholesale; gateway auth schemes that reuse protocol header names.","solutions":["Remove all reserved names from the helper output; keep only genuinely custom headers (e.g. X-Api-Key, X-Org-Id)","Supply auth through the client's configured headers/OAuth flow instead of the helper","If you need a proxy auth header, use Proxy-Authorization (explicitly allowed for IAP-style setups)","Add a filter step in the helper that drops the reserved set before printing"],"exampleFix":"# before\n{\"Authorization\":\"Bearer eyJ...\",\"X-Api-Key\":\"k\"}\n\n# after\n{\"X-Api-Key\":\"k\"}   # Authorization is managed by OAuth/bearer config","handlingStrategy":"validation","validationCode":"# Fail if the helper output contains any reserved header name\nRESERVED=\"accept authorization connection content-encoding content-length content-type host keep-alive last-event-id mcp-protocol-version mcp-session-id origin proxy-connection referer te trailer transfer-encoding upgrade\"\ncd \"$MCP_CWD\" && env -i PATH=/usr/bin:/bin sh -c \"$HTTP_HEADERS_HELPER\" \\\n  | jq -r 'keys[] | ascii_downcase' | while IFS= read -r name; do\n      case \" $RESERVED \" in *\" $name \"*) echo \"reserved: $name\";; esac\n  done","typeGuard":"const RESERVED: &[&str] = &[\"accept\",\"authorization\",\"connection\",\"content-encoding\",\"content-length\",\"content-type\",\"host\",\"keep-alive\",\"last-event-id\",\"mcp-protocol-version\",\"mcp-session-id\",\"origin\",\"proxy-connection\",\"referer\",\"te\",\"trailer\",\"transfer-encoding\",\"upgrade\"];\n\nfn is_reserved_header(name: &str) -> bool {\n    RESERVED.contains(&name.to_ascii_lowercase().as_str())\n}","tryCatchPattern":null,"preventionTips":["Filter the reserved set inside the helper before printing","Use configured headers/OAuth for Authorization — never the helper","Prefer X- prefixed custom header names to avoid protocol collisions","Document the reserved list next to your helper's contract"],"tags":["rust","mcp","headers-helper","reserved-headers","http-headers","authorization"],"backgroundTag":"reserved-header-rejected","analyzedSha":"339751715c64496cb86246bfb3935f40e309dd3d","analyzedAt":"2026-08-25T05:35:09.876Z","schemaVersion":2},"datasetVersion":"2026-08-25T06:17:31.827Z"}