PrefectHQ/fastmcp · error · CIMDFetchError
str(e)
Error message
str(e)
What it means
When the SSRF-safe fetch layer fails at the transport level (connection errors, HTTP error statuses outside the allowed codes, timeouts), it raises SSRFFetchError. CIMDFetcher.fetch() wraps that message in CIMDFetchError, the fetch-specific exception type, so callers can distinguish 'could not retrieve document' from 'document invalid'.
Source
Thrown at fastmcp_slim/fastmcp/server/auth/cimd.py:365
if cached.last_modified:
request_headers["If-Modified-Since"] = cached.last_modified
if request_headers:
allowed_status_codes = {200, 304}
try:
response = await ssrf_safe_fetch_response(
client_id_url,
require_path=True,
max_size=self.MAX_RESPONSE_SIZE,
timeout=self.timeout,
overall_timeout=30.0,
request_headers=request_headers,
allowed_status_codes=allowed_status_codes,
)
except SSRFError as e:
raise CIMDValidationError(str(e)) from e
except SSRFFetchError as e:
raise CIMDFetchError(str(e)) from e
if response.status_code == 304:
if cached is None:
raise CIMDFetchError(
"CIMD server returned 304 Not Modified without cached document"
)
now = time.time()
if self._has_freshness_headers(response.headers):
policy = self._parse_cache_policy(response.headers, now)
else:
# RFC allows 304 to omit unchanged headers. Preserve existing
# cache policy rather than resetting to fallback defaults.
policy = _CIMDCachePolicy(
etag=None,
last_modified=None,
expires_at=now + cached.freshness_lifetime,
freshness_lifetime=cached.freshness_lifetime,View on GitHub (pinned to 1f02114297)
Solutions
- Verify the client_id URL is live and serves the CIMD document (curl it from the server host)
- Check for DNS/TLS/proxy issues on the FastMCP server's outbound network
- Catch CIMDFetchError and reject the request with invalid_client; the remote document owner must fix hosting
- Retry with backoff only for transient statuses if you control the fetch policy
Example fix
try:
doc = await fetcher.get_client(client_id)
except CIMDFetchError as e:
logger.warning("CIMD fetch failed for %s: %s", client_id, e)
raise InvalidClientError() from e Defensive patterns
Strategy: try-catch
Try / catch
try:
doc = await fetcher.get_client(client_id)
except CIMDFetchError as e:
logger.warning("CIMD fetch failed: %s", e)
raise InvalidClientError() from e Prevention
- Monitor uptime of metadata hosting endpoints
- Set reasonable fetch timeouts and allowed_status_codes for your environment
- Verify the client_id URL is reachable from the server's network (egress firewalls)
When it happens
Trigger: CIMDFetcher.fetch/get_client called with a client_id URL whose host is unreachable, returns 4xx/5xx (unless in allowed_status_codes), times out, or drops the connection.
Common situations: The client's metadata hosting site is down or misconfigured (404, DNS gone); TLS certificate errors; corporate firewalls blocking the server's outbound request; client removed their CIMD document after issuing a client_id.
Related errors
- Unexpected authorization response: {response.status_code}
- {str(e) from SSRFError/SSRFFetchError}
- Invalid client assertion: {e}
- CIMD redirect_uri must have a host: {uri!r}
- CIMD server returned 304 Not Modified without cached documen
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/2bdffb4cad8ca80d.
Report an issue: GitHub.