openai/codex · error
MCP HTTP headers helper returned a reserved header
Error message
MCP HTTP headers helper returned a reserved header
What it means
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.
Source
Thrown at codex-rs/rmcp-client/src/http_headers.rs:391
| "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"
) {
return Err(anyhow!(
"MCP HTTP headers helper returned a reserved header"
));
}
if parsed.contains_key(&name) {
return Err(anyhow!(
"MCP HTTP headers helper returned duplicate header names"
));
}
let value = HeaderValue::from_str(&value)
.map_err(|_| anyhow!("MCP HTTP headers helper returned an invalid header value"))?;
parsed.insert(name, value);
}
Ok(parsed)
}
#[cfg(test)]
#[path = "http_headers_tests.rs"]
mod tests;View on GitHub (pinned to 339751715c)
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
Example fix
# before
{"Authorization":"Bearer eyJ...","X-Api-Key":"k"}
# after
{"X-Api-Key":"k"} # Authorization is managed by OAuth/bearer config Defensive patterns
Strategy: validation
Validate before calling
# Fail if the helper output contains any reserved header name
RESERVED="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"
cd "$MCP_CWD" && env -i PATH=/usr/bin:/bin sh -c "$HTTP_HEADERS_HELPER" \
| jq -r 'keys[] | ascii_downcase' | while IFS= read -r name; do
case " $RESERVED " in *" $name "*) echo "reserved: $name";; esac
done Type guard
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"];
fn is_reserved_header(name: &str) -> bool {
RESERVED.contains(&name.to_ascii_lowercase().as_str())
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- MCP HTTP headers helper returned duplicate header names
- invalid HTTP header: {0}
- MCP HTTP headers helper containment failed: {error}
- MCP HTTP headers helper failed to start: {error}
- MCP HTTP headers helper process id was unavailable
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/ccd82752a155f63e.
Report an issue: GitHub.