openai/codex · error

MCP HTTP headers helper wrote non-UTF-8 data

Error message

MCP HTTP headers helper wrote non-UTF-8 data

What it means

Helper stdout must decode as UTF-8 (String::from_utf8) before any JSON parsing happens; this error fires when the bytes are not valid UTF-8. Binary output, UTF-16 from Windows tools, Latin-1 text, or encrypted blobs all land here. The message deliberately does not include the offending bytes, so secrets never leak into logs.

Source

Thrown at codex-rs/rmcp-client/src/http_headers.rs:350

            return Err(anyhow!("MCP HTTP headers helper output exceeds 64 KiB"));
        }
        let status = process.child.wait().await?;
        if !status.success() {
            return Err(anyhow!(
                "MCP HTTP headers helper exited with status {status}"
            ));
        }
        Ok(output)
    })
    .await
    .map_err(|_| anyhow!("MCP HTTP headers helper timed out after 10 seconds"))??;

    parse_helper_output(output)
}

fn parse_helper_output(stdout: Vec<u8>) -> Result<HeaderMap> {
    let stdout = String::from_utf8(stdout)
        .map_err(|_| anyhow!("MCP HTTP headers helper wrote non-UTF-8 data"))?;
    let mut deserializer = serde_json::Deserializer::from_str(stdout.trim());
    let headers = RawHeaderEntries::deserialize(&mut deserializer)
        .and_then(|headers| {
            deserializer.end()?;
            Ok(headers)
        })
        .map_err(|_| anyhow!("MCP HTTP headers helper must output a JSON object of strings"))?;
    if headers.has_exact_duplicate {
        return Err(anyhow!(
            "MCP HTTP headers helper returned duplicate header names"
        ));
    }
    let mut parsed = HeaderMap::with_capacity(headers.entries.len());
    for (name, value) in headers.entries {
        let name = HeaderName::from_bytes(name.as_bytes())
            .map_err(|_| anyhow!("MCP HTTP headers helper returned an invalid header name"))?;
        // Helper values replace same-name configured headers; bearer/OAuth owns Authorization.
        // Google IAP uses Proxy-Authorization alongside application Authorization. For HTTPS MCP

View on GitHub (pinned to 339751715c)

Solutions

  1. Ensure the helper prints only UTF-8 JSON on stdout
  2. Force UTF-8 in the helper (e.g. [Console]::OutputEncoding = UTF8 in PowerShell, LC_ALL=C.UTF-8)
  3. Never cat binary files; extract and print only the needed string values
  4. Verify with: sh -c "$CMD" | iconv -f UTF-8 -t UTF-8 >/dev/null && echo ok

Example fix

# before: helper cats a UTF-16/binary credential file
# after
printf '{"X-Api-Key":"%s"}' "$(extract_ascii_key ~/.creds/bin)"
Defensive patterns

Strategy: validation

Validate before calling

# Fail fast if stdout is not valid UTF-8
cd "$MCP_CWD" && env -i PATH=/usr/bin:/bin sh -c "$HTTP_HEADERS_HELPER" \
  | iconv -f UTF-8 -t UTF-8 >/dev/null && echo utf8-ok || echo non-utf8-output

Type guard

fn is_helper_non_utf8(error: &anyhow::Error) -> bool {
    error.to_string().contains("non-UTF-8")
}

Prevention

When it happens

Trigger: A helper writing raw binary to stdout (cat of a binary file), a Windows tool emitting UTF-16, or any program printing bytes outside valid UTF-8 sequences.

Common situations: Debug scripts dumping binary artifacts; PowerShell tools writing UTF-16 by default; encrypted or compressed credential blobs printed verbatim; locale-dependent output.

Related errors


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/a62ac628725baaac. Report an issue: GitHub.