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
- Raise max_size to accommodate the expected document (e.g. max_size=65536).
- Confirm the URL points to a compact JSON metadata document, not an HTML page.
- 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.
- 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
- Set max_size to the documented upper bound of the payload type
- Point fetches at compact JSON endpoints, not HTML pages
- Keep the default 5KB cap unless the format justifies more
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
- HTTP {response.status_code} fetching {url}
- Response too large: exceeded {max_size} bytes
- Unexpected authorization response: {response.status_code}
- {str(e) from SSRFError/SSRFFetchError}
- str(e)
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/aef376194febce51.
Report an issue: GitHub.