openai/codex · error · StreamableHttpClientAdapterError

MCP response body exceeds {maximum_bytes} bytes

Error message

MCP response body exceeds {maximum_bytes} bytes

What it means

collect_body() buffers non-streaming JSON bodies — POST application/json responses, server/discover, and events/stream requests — and enforces a hard cap: MAX_MCP_STDIO_LINE_BYTES for discovery/modern-protocol (2026-07-28) requests and MAX_EVENT_NOTIFICATION_BYTES for event-stream requests. When the accumulated body would cross maximum_bytes, the adapter returns ResponseTooLarge with the limit instead of letting a hostile or misconfigured server exhaust orchestrator memory.

Source

Thrown at codex-rs/rmcp-client/src/http_client_adapter.rs:112

impl Drop for EventStreamCancellation {
    fn drop(&mut self) {
        self.cancellations
            .lock()
            .unwrap_or_else(PoisonError::into_inner)
            .remove(&self.request_id);
    }
}

#[derive(Debug, thiserror::Error)]
pub(crate) enum StreamableHttpClientAdapterError {
    #[error("streamable HTTP session expired with 404 Not Found")]
    SessionExpired404,
    #[error(transparent)]
    HttpRequest(#[from] ExecServerError),
    #[error("invalid HTTP header: {0}")]
    Header(String),
    #[error("MCP response body exceeds {maximum_bytes} bytes")]
    ResponseTooLarge { maximum_bytes: usize },
}

impl StreamableHttpClientAdapter {
    pub(crate) fn new(
        http_client: Arc<dyn HttpClient>,
        default_headers: HeaderMap,
        auth_provider: Option<SharedAuthProvider>,
        has_configured_headers: bool,
        redirect_mode: StreamableHttpRedirectMode,
        initialize_deadline: Arc<Mutex<Option<Instant>>>,
    ) -> Self {
        Self {
            http_client: Arc::new(SameOriginRedirectHttpClient::new(http_client)),
            default_headers,
            auth_provider,
            event_stream_cancellations: Arc::default(),
            has_configured_headers,

View on GitHub (pinned to 339751715c)

Solutions

  1. Shrink the server response: paginate tools/list, trim tool descriptions/schemas, stop inlining large content
  2. Verify the configured URL is a real MCP endpoint, not a page that returns a huge body
  3. Move large payloads out-of-band (resource URIs fetched separately)
  4. If you hit this on discovery only, check whether the server supports the modern protocol path so limits apply correctly

Example fix

# before: tools/list returns every tool with full schemas in one body -> ResponseTooLarge
# after: request pages
{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{"cursor":"...","limit":100}}
Defensive patterns

Strategy: try-catch

Type guard

fn is_response_too_large(error: &rmcp::service::ServiceError) -> bool {
    error.to_string().contains("MCP response body exceeds")
}

Try / catch

match client.list_tools(Default::default()).await {
    Ok(tools) => Ok(tools),
    Err(e) if e.to_string().contains("MCP response body exceeds") => {
        // server payload too big: reduce it (pagination/trimming), then retry
        Err(anyhow!(e).context("MCP response too large; shrink server payload"))
    }
    Err(e) => Err(e.into()),
}

Prevention

When it happens

Trigger: A server/discover or modern-protocol JSON response, or an events/stream POST body, whose total size exceeds the configured maximum; raised at the first chunk that makes body.len() pass maximum_bytes in collect_body().

Common situations: Very large tools/list or discovery payloads (thousands of embedded tool schemas); servers inlining base64 blobs or whole resources into one response; a wrong endpoint returning an HTML page; proxies that buffer and re-send giant error payloads.

Related errors


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