PrefectHQ/fastmcp · error · SSRFFetchError

Response too large: {size} bytes (max {max_size})

Error message

Response too large: {size} bytes (max {max_size})

What it means

ssrf_safe_fetch_response enforces a max_size limit (default 5120 bytes) using the Content-Length response header before downloading. If the declared body exceeds the cap, SSRFFetchError is raised immediately without streaming the body. This prevents a malicious host from announcing or delivering arbitrarily large payloads during SSRF-guarded fetches.

Source

Thrown at fastmcp_slim/fastmcp/server/auth/ssrf.py:503

                    "GET",
                    target.url,
                    headers=headers,
                    extensions=extensions,
                ) as response,
            ):
                if time.monotonic() - start_time > overall_timeout:
                    raise SSRFFetchError(f"Overall timeout exceeded: {url}")

                if response.status_code not in expected_statuses:
                    raise SSRFFetchError(f"HTTP {response.status_code} fetching {url}")

                # Check Content-Length header first if available
                content_length = response.headers.get("content-length")
                if content_length:
                    try:
                        size = int(content_length)
                        if size > max_size:
                            raise SSRFFetchError(
                                f"Response too large: {size} bytes (max {max_size})"
                            )
                    except ValueError:
                        pass

                # Stream the response and enforce size limit during download
                chunks = []
                total = 0
                async for chunk in response.aiter_bytes():
                    if time.monotonic() - start_time > overall_timeout:
                        raise SSRFFetchError(f"Overall timeout exceeded: {url}")
                    total += len(chunk)
                    if total > max_size:
                        raise SSRFFetchError(
                            f"Response too large: exceeded {max_size} bytes"
                        )
                    chunks.append(chunk)

View on GitHub (pinned to 1f02114297)

Solutions

  1. Raise max_size to accommodate the expected document (e.g. max_size=65536).
  2. Confirm the URL points to a compact JSON metadata document, not an HTML page.
  3. If the host lies about Content-Length, note the streaming path (error 385) also caps actual bytes, so both header and streamed sizes must fit.
  4. Catch SSRFFetchError and report/document the size limit to callers.

Example fix

// before
resp = await ssrf_safe_fetch_response(url)  # max_size=5120 default
// after
resp = await ssrf_safe_fetch_response(url, max_size=64 * 1024)
Defensive patterns

Strategy: validation

Validate before calling

# pre-flight size check
head = await client.head(url)
cl = int(head.headers.get("content-length", "0"))
assert cl <= max_size, f"body {cl}B exceeds max_size {max_size}B"

Try / catch

try:
    resp = await ssrf_safe_fetch_response(url, max_size=65536)
except SSRFFetchError as e:
    if "Response too large" in str(e):
        raise PayloadTooLarge(url) from e
    raise

Prevention

When it happens

Trigger: Fetching a URL whose server sends Content-Length larger than max_size (e.g. fetching a large page with default 5 KB cap); a hostile endpoint deliberately returning a huge declared size to probe the guard.

Common situations: Pointing fetch at an HTML page instead of a small JSON metadata document; CIMD metadata that includes extra fields pushing past 5 KB; proxies adding content that inflates the body.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/aef376194febce51. Report an issue: GitHub.