conductor-oss/conductor · error · RuntimeException
MCP response exceeds the 10 MiB payload limit
Error message
MCP response exceeds the 10 MiB payload limit
What it means
Thrown by readBoundedBody when the response body's declared Content-Length exceeds ExternalDataLimits.MAX_PAYLOAD_BYTES (10 MiB). This is the pre-read size guard: it checks the server-advertised length before streaming, so an oversized response is rejected without being downloaded. Protects against memory/exhaustion attacks from a malicious or buggy MCP server.
Source
Thrown at ai/src/main/java/org/conductoross/conductor/ai/mcp/MCPService.java:443
|| request.header("Proxy-Authorization") != null;
}
private boolean isSameOrigin(String firstUrl, String secondUrl) {
okhttp3.HttpUrl first = okhttp3.HttpUrl.parse(firstUrl);
okhttp3.HttpUrl second = okhttp3.HttpUrl.parse(secondUrl);
return first != null
&& second != null
&& first.scheme().equalsIgnoreCase(second.scheme())
&& first.host().equalsIgnoreCase(second.host())
&& first.port() == second.port();
}
private String readBoundedBody(ResponseBody body) throws Exception {
if (body == null) {
return "";
}
if (body.contentLength() > ExternalDataLimits.MAX_PAYLOAD_BYTES) {
throw new RuntimeException("MCP response exceeds the 10 MiB payload limit");
}
try (body) {
okio.Buffer buffer = new okio.Buffer();
long total = 0;
long read;
while ((read = body.source().read(buffer, 8192)) != -1) {
total += read;
if (total > ExternalDataLimits.MAX_PAYLOAD_BYTES) {
buffer.clear();
throw new RuntimeException("MCP response exceeds the 10 MiB payload limit");
}
}
return buffer.readUtf8();
}
}
private record ResponsePayload(int statusCode, String contentType, String body) {}
View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Reduce the size of what the server returns (paginate tools, trim descriptions, avoid embedding large blobs in tool results).
- If a larger limit is genuinely required and trusted, raise ExternalDataLimits.MAX_PAYLOAD_BYTES (weigh memory/exhaustion risk first).
- Confirm the server isn't accidentally returning a binary payload as text.
- For large tool outputs, have the tool return a reference/URL instead of inline content.
Defensive patterns
Strategy: validation
Validate before calling
// There is no pre-call API to know response size; the guard runs server-side. // Mitigate by ensuring the server does not return >10MiB (paginate tools, trim descriptions).
Try / catch
try {
mcpService.listTools(serverUrl, headers);
} catch (RuntimeException e) {
if (e.getMessage().contains("payload limit")) {
// server response too large; reduce tool count/description size server-side
}
throw e;
} Prevention
- Paginate or trim large tool catalogs/results on the server.
- Return references/URLs for large blobs instead of inline content.
- Only raise MAX_PAYLOAD_BYTES on a trusted server after assessing memory risk.
When it happens
Trigger: Server sets Content-Length to a value > 10 MiB on the JSON-RPC response (e.g. a tools/list returning an enormous tool catalog, or a tool result with a huge embedded blob). The check fires before any bytes are buffered.
Common situations: MCP server returning very large tool descriptions or tool results; a server streaming a file/blob through a text content item; an adversarial server attempting resource exhaustion.
Related errors
- Refusing to forward credentials across an MCP redirect
- MCP headers must not contain CR or LF characters
- plannerContext header '${name}' contains CR/LF — rejected to
- Skill package exceeds max uncompressed size of {maxUncompres
- Invalid skill package path: {name}
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/4637d7227c010cb8.
Report an issue: GitHub.