{"record":{"id":"aea93b7202fa2b09","repo":"RightNow-AI/openfang","slug":"mcp-message-too-large-content-length-bytes-max","errorCode":null,"errorMessage":"MCP message too large: {content_length} bytes (max {MAX_MCP_MESSAGE_SIZE})","messagePattern":"MCP message too large: (.+?) bytes \\(max (.+?)\\)","errorType":"error_code","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/openfang-cli/src/mcp.rs","lineNumber":200,"sourceCode":"\n    if content_length == 0 {\n        return Ok(None);\n    }\n\n    // SECURITY: Reject oversized messages to prevent OOM.\n    const MAX_MCP_MESSAGE_SIZE: usize = 10 * 1024 * 1024; // 10MB\n    if content_length > MAX_MCP_MESSAGE_SIZE {\n        // Drain the oversized body to avoid stream desync\n        let mut discard = [0u8; 4096];\n        let mut remaining = content_length;\n        while remaining > 0 {\n            let to_read = remaining.min(4096);\n            if reader.read_exact(&mut discard[..to_read]).is_err() {\n                break;\n            }\n            remaining -= to_read;\n        }\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            format!(\"MCP message too large: {content_length} bytes (max {MAX_MCP_MESSAGE_SIZE})\"),\n        ));\n    }\n\n    // Read the body\n    let mut body = vec![0u8; content_length];\n    reader.read_exact(&mut body)?;\n\n    match serde_json::from_slice(&body) {\n        Ok(v) => Ok(Some(v)),\n        Err(_) => Ok(None),\n    }\n}\n\n/// Write a Content-Length framed JSON-RPC response to the writer.\nfn write_message(writer: &mut impl Write, msg: &Value) {\n    let body = serde_json::to_string(msg).unwrap_or_default();","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/RightNow-AI/openfang/blob/acf2587e46be174c10200489c9a2d23a39a98aeb/crates/openfang-cli/src/mcp.rs#L182-L218","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (client sends one huge message)\nlet body = serde_json::to_vec(&huge_request)?; // e.g. 50 MB tool result\nwrite_message(stdout, &body)?;\n// after (truncate/summarize before sending)\nlet body = serde_json::to_vec(&truncate_request(&huge_request, 1_000_000))?;\nwrite_message(stdout, &body)?;","handlingStrategy":"try-catch","validationCode":"// client-side, before writing a message to the MCP server's stdin\nlet body = serde_json::to_vec(&request)?;\nif body.len() > MAX_MCP_MESSAGE_SIZE {\n    return Err(anyhow!(\"payload {} bytes exceeds MCP max {}; truncate or split\", body.len(), MAX_MCP_MESSAGE_SIZE));\n}","typeGuard":"fn message_size_ok(body: &[u8], max: usize) -> bool { body.len() <= max }","tryCatchPattern":"match write_message(child.stdin.as_mut().unwrap(), &body) {\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidData && e.to_string().contains(\"too large\") => {\n        eprintln!(\"MCP message over the size cap; truncate tool output or split the request\");\n        // fall back to a summarized/shorter request\n    }\n    other => other?,\n}","preventionTips":["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"],"tags":["mcp","io","message-size","protocol"],"backgroundTag":"mcp-message-too-large","analyzedSha":"acf2587e46be174c10200489c9a2d23a39a98aeb","analyzedAt":"2026-09-02T22:42:28.464Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}