modelcontextprotocol/servers · error · Error

Content-Length for ${url} exceeds max of ${maxBytes}: ${cont

Error message

Content-Length for ${url} exceeds max of ${maxBytes}: ${contentLength}

What it means

Thrown by `fetchSafely` as an early bail-out when the response's `Content-Length` header, if present, already exceeds `GZIP_MAX_FETCH_SIZE` (default 10 MB, env-configurable). This avoids downloading an obviously-too-large file. The code explicitly notes Content-Length is not trusted as the sole source of truth (see error 12 for the streaming guard).

Source

Thrown at src/everything/tools/gzip-file-as-resource.ts:206

        `Fetching ${url} took more than ${timeoutMillis} ms and was aborted.`
      ),
    timeoutMillis
  );

  try {
    // Fetch the data
    const response = await fetch(url, { signal: controller.signal });
    if (!response.body) {
      throw new Error("No response body");
    }

    // Note: we can't trust the Content-Length header: a malicious or clumsy server could return much more data than advertised.
    // We check it here for early bail-out, but we still need to monitor actual bytes read below.
    const contentLengthHeader = response.headers.get("content-length");
    if (contentLengthHeader != null) {
      const contentLength = parseInt(contentLengthHeader, 10);
      if (contentLength > maxBytes) {
        throw new Error(
          `Content-Length for ${url} exceeds max of ${maxBytes}: ${contentLength}`
        );
      }
    }

    // Read the fetched data from the response body
    const reader = response.body.getReader();
    const chunks = [];
    let totalSize = 0;

    // Read chunks until done
    try {
      while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        totalSize += value.length;

View on GitHub (pinned to 76d64c822f)

Solutions

  1. Fetch a smaller file that fits under the cap.
  2. Raise the cap via `GZIP_MAX_FETCH_SIZE` env var (bytes), e.g. `GZIP_MAX_FETCH_SIZE=50000000`.
  3. Pre-check the remote size with a HEAD request and skip/warn before calling the tool.

Example fix

# before (default 10MB cap, file is 50MB)
# after
GZIP_MAX_FETCH_SIZE=50000000 node ...
Defensive patterns

Strategy: validation

Validate before calling

const MAX = Number(process.env.GZIP_MAX_FETCH_SIZE ?? 10*1024*1024);
async function sizeOk(url: string): Promise<boolean> {
  const h = await fetch(url, { method: 'HEAD' });
  const len = Number(h.headers.get('content-length') ?? 0);
  return len <= MAX;
}

Try / catch

try {
  await callGzipTool({ data: url });
} catch (e) {
  if (e instanceof Error && e.message.includes('Content-Length')) {
    // raise GZIP_MAX_FETCH_SIZE or pick a smaller file
  }
}

Prevention

When it happens

Trigger: The remote URL advertises a `Content-Length` greater than `maxBytes`. `parseInt(contentLength, 10)` is compared against the cap; e.g. an 11 MB file with the default 10 MB cap.

Common situations: Fetching a file larger than the default 10 MB cap, or an operator who lowered `GZIP_MAX_FETCH_SIZE` for testing/safety. Note a malicious server could under-report Content-Length — the streaming guard (error 12) catches that.

Related errors


AI-assisted analysis of modelcontextprotocol/servers@76d64c822f (2026-08-12). Data as JSON: /api/errors/3ce5ebd3ecfb3e4b. Report an issue: GitHub.