RightNow-AI/openfang · error · io::Error
MCP message too large: {content_length} bytes (max {MAX_MCP_
Error message
MCP message too large: {content_length} bytes (max {MAX_MCP_MESSAGE_SIZE}) What it means
The MCP server reads length-prefixed JSON-RPC messages from stdin and rejects any message whose declared content length exceeds MAX_MCP_MESSAGE_SIZE, returning an InvalidData io::Error (after draining what it can). This guard prevents a peer from forcing unbounded memory allocation via a huge length header.
Source
Thrown at crates/openfang-cli/src/mcp.rs:200
if content_length == 0 {
return Ok(None);
}
// SECURITY: Reject oversized messages to prevent OOM.
const MAX_MCP_MESSAGE_SIZE: usize = 10 * 1024 * 1024; // 10MB
if content_length > MAX_MCP_MESSAGE_SIZE {
// Drain the oversized body to avoid stream desync
let mut discard = [0u8; 4096];
let mut remaining = content_length;
while remaining > 0 {
let to_read = remaining.min(4096);
if reader.read_exact(&mut discard[..to_read]).is_err() {
break;
}
remaining -= to_read;
}
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("MCP message too large: {content_length} bytes (max {MAX_MCP_MESSAGE_SIZE})"),
));
}
// Read the body
let mut body = vec![0u8; content_length];
reader.read_exact(&mut body)?;
match serde_json::from_slice(&body) {
Ok(v) => Ok(Some(v)),
Err(_) => Ok(None),
}
}
/// Write a Content-Length framed JSON-RPC response to the writer.
fn write_message(writer: &mut impl Write, msg: &Value) {
let body = serde_json::to_string(msg).unwrap_or_default();View on GitHub (pinned to acf2587e46)
Solutions
- Split oversized payloads into multiple MCP messages / batch requests so each message stays under MAX_MCP_MESSAGE_SIZE
- Inspect what the client is writing to the server's stdin and check the Content-Length framing (length must be the exact byte count of the JSON body, in ASCII digits followed by \r\n)
- Raise the server's maximum message size if legitimate messages are genuinely large (configure/increase MAX_MCP_MESSAGE_SIZE in crates/openfang-cli/src/mcp.rs) and restart the daemon
- Check the client library version for known framing bugs; upgrade or downgrade to a version that frames messages correctly
- Validate and sanitize upstream data (truncate tool outputs) before sending them over MCP
Example fix
// before (client sends one huge message) let body = serde_json::to_vec(&huge_request)?; // e.g. 50 MB tool result write_message(stdout, &body)?; // after (truncate/summarize before sending) let body = serde_json::to_vec(&truncate_request(&huge_request, 1_000_000))?; write_message(stdout, &body)?;
Defensive patterns
Strategy: try-catch
Validate before calling
// client-side, before writing a message to the MCP server's stdin
let body = serde_json::to_vec(&request)?;
if body.len() > MAX_MCP_MESSAGE_SIZE {
return Err(anyhow!("payload {} bytes exceeds MCP max {}; truncate or split", body.len(), MAX_MCP_MESSAGE_SIZE));
} Type guard
fn message_size_ok(body: &[u8], max: usize) -> bool { body.len() <= max } Try / catch
match write_message(child.stdin.as_mut().unwrap(), &body) {
Err(e) if e.kind() == std::io::ErrorKind::InvalidData && e.to_string().contains("too large") => {
eprintln!("MCP message over the size cap; truncate tool output or split the request");
// fall back to a summarized/shorter request
}
other => other?,
} Prevention
- Measure the serialized byte length before sending; never assume payload size
- Truncate or chunk large tool outputs before framing them over MCP
- Keep Content-Length framing exact: ASCII byte count + \r\n + body
- Pin compatible client/server versions so MAX_MCP_MESSAGE_SIZE assumptions match
- Watch stdin of the server for repeated size errors indicating a buggy client
When it happens
Trigger: An MCP client sends a Content-Length header larger than MAX_MCP_MESSAGE_SIZE: a malicious or buggy client, a corrupted/framed stream where a payload byte is misread as a length digit, a client that does not chunk or truncate large tool results, or a proxy mangling framing so the length field is garbage.
Common situations: Piping large files or long tool outputs through an MCP client; a misbehaving LLM client library that serializes huge tool results in one message; feeding raw logs into the server's stdin; running an old/new client against a server with a different size cap.
Related errors
AI-assisted analysis of RightNow-AI/openfang@acf2587e46 (2026-09-02).
Data as JSON: /api/errors/aea93b7202fa2b09.
Report an issue: GitHub.