BigPizzaV3/CodexPlusPlus · error · anyhow::Error
不支持的 Content-Encoding:{encoding}
Error message
不支持的 Content-Encoding:{encoding} What it means
decode_protocol_proxy_request_body (crates/codex-plus-core/src/launcher.rs:1302-1303) accepts exactly three Content-Encoding values for Responses bodies forwarded through the local proxy: absent/empty, `identity`, and `zstd`. Anything else — gzip, br, deflate, x-gzip, or a typo — fails before decoding with this message. The proxy pipeline only implements zstd decoding, so other encodings are explicitly unsupported rather than silently mis-parsed.
Source
Thrown at crates/codex-plus-core/src/launcher.rs:1303
fn decode_protocol_proxy_request_body(
body: &[u8],
content_encoding: Option<&str>,
) -> anyhow::Result<String> {
let encoding = content_encoding.unwrap_or_default().trim();
let decoded = if encoding.is_empty() || encoding.eq_ignore_ascii_case("identity") {
body.to_vec()
} else if encoding.eq_ignore_ascii_case("zstd") {
let decoder = zstd::stream::read::Decoder::new(std::io::Cursor::new(body))?;
let mut limited = decoder.take((MAX_HTTP_BODY_BYTES + 1) as u64);
let mut decoded = Vec::new();
limited.read_to_end(&mut decoded)?;
if decoded.len() > MAX_HTTP_BODY_BYTES {
anyhow::bail!("解压后的请求体超过大小限制");
}
decoded
} else {
anyhow::bail!("不支持的 Content-Encoding:{encoding}");
};
String::from_utf8(decoded)
.map_err(|error| anyhow::anyhow!("Responses 请求体不是 UTF-8:{error}"))
}
fn overlay_image_response() -> (String, Vec<u8>, String, &'static str) {
let not_found = || {
(
"404 Not Found".to_string(),
serde_json::to_vec(&serde_json::json!({
"status": "failed",
"message": "图片覆盖层未启用或图片不可用"
}))
.unwrap_or_default(),
"application/json; charset=utf-8".to_string(),
"helper.overlay_image_not_found",
)View on GitHub (pinned to 1f431ae49b)
Solutions
- Make the client send the body uncompressed: disable automatic compression for requests to the local proxy (reqwest: build the client without gzip/brotli features or .no_gzip().no_brotli(); fetch/axios: skip compression headers)
- Re-encode as zstd if you must compress: Content-Encoding: zstd is the only compressed form the proxy decodes
- If you control the core, extend the matcher at launcher.rs:1291-1304 with a gzip branch (flate2::read::GzDecoder) plus tests mirroring the zstd ones
Example fix
// before: gzip-compressed body trips the guard
let mut res = surf::post(url)
.header("content-encoding", "gzip")
.body(gzip_compress(body))
.await?; // bail: 不支持的 Content-Encoding:gzip
// after: identity body passes
let mut res = surf::post(url)
.header("content-encoding", "identity")
.body(body)
.await?; Defensive patterns
Strategy: validation
Validate before calling
// Validate the header before sending
fn proxy_supported_encoding(enc: Option<&str>) -> bool {
matches!(enc.map(str::trim), None | Some("") | Some("identity") | Some("zstd") | Some("ZSTD"))
}
assert!(proxy_supported_encoding(request_headers().get("content-encoding"))); Type guard
fn is_supported_content_encoding(value: &str) -> bool {
let v = value.trim();
v.is_empty() || v.eq_ignore_ascii_case("identity") || v.eq_ignore_ascii_case("zstd")
} Try / catch
// Server side: map to 415 Unsupported Media Type
let body = match decode_protocol_proxy_request_body(&raw, content_encoding) {
Err(e) if e.to_string().starts_with("不支持的 Content-Encoding") => {
return http_415_unsupported_media_type();
}
r => r?,
}; Prevention
- Build HTTP clients with compression disabled for local proxy targets (reqwest: .no_gzip().no_brotli().no_deflate())
- Standardize on zstd (the only codec the proxy decodes) when compression is required
- Never place a compressing reverse proxy in front of the loopback helper
When it happens
Trigger: POSTing to the local helper/proxy Responses endpoint with `Content-Encoding: gzip` (or br/deflate) on the body; an HTTP client library with automatic transparent compression enabled (e.g. reqwest gzip feature sending gzip automatically); a middleware chain that re-encodes the body between client and proxy.
Common situations: Switching the client stack to one that defaults to gzip compression; adding a compressing reverse proxy in front of the loopback helper; version change where the client began negotiating br with a CDN and forwards the encoded body verbatim; hand-rolled fetch code setting Content-Encoding manually.
Related errors
- 解压后的请求体超过大小限制
- Responses 请求体不是 UTF-8:{error}
- provider sync requires launcher hooks with codex-plus-data i
- Remote Control session recovery requires launcher hooks with
- macOS open command is empty
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@1f431ae49b (2026-08-16).
Data as JSON: /api/errors/ffb64dcaf5734437.
Report an issue: GitHub.