PrefectHQ/fastmcp · error · ValueError
Client must have CIMD document for private_key_jwt
Error message
Client must have CIMD document for private_key_jwt
What it means
`CIMDClientManager.validate_private_key_jwt` requires the client object to carry a loaded CIMD document (`client.cimd_document`) before it can validate a private_key_jwt assertion. If the attribute is missing or falsy, there is no metadata containing the client's public keys, so validation cannot proceed and the library raises ValueError.
Source
Thrown at fastmcp_slim/fastmcp/server/auth/cimd.py:817
assertion: str,
client, # OAuthProxyClient, untyped to avoid circular import
token_endpoint: str,
) -> bool:
"""Validate JWT assertion for private_key_jwt auth.
Args:
assertion: JWT assertion string from client
client: OAuth proxy client (must have cimd_document)
token_endpoint: Token endpoint URL for aud validation
Returns:
True if assertion is valid
Raises:
ValueError: If client doesn't have CIMD document or validation fails
"""
if not hasattr(client, "cimd_document") or not client.cimd_document:
raise ValueError("Client must have CIMD document for private_key_jwt")
cimd_doc = client.cimd_document
if cimd_doc.token_endpoint_auth_method != "private_key_jwt":
raise ValueError("CIMD document must specify private_key_jwt auth method")
return await self._assertion_validator.validate_assertion(
assertion, client.client_id, token_endpoint, cimd_doc
)
View on GitHub (pinned to 1f02114297)
Solutions
- Ensure the client_id resolves to a valid CIMD document and that it is loaded before authentication (fix the CIMD URL / re-trigger discovery)
- If the client is not CIMD-registered, use the auth method actually configured for it instead of private_key_jwt
- Check server logs/upstream fetch for the earlier CIMD-document load failure and correct the root cause
- Register the client's metadata in a reachable CIMD document containing its public keys
Example fix
# before: client without loaded metadata sending private_key_jwt # after: point client_id at a valid CIMD document client_id = "https://client.example.com/client-metadata.json" # must fetch and expose cimd_document
Defensive patterns
Strategy: validation
Validate before calling
if not getattr(client, "cimd_document", None):
raise RuntimeError("Client CIMD document not loaded; cannot use private_key_jwt") Type guard
def has_cimd_document(client) -> bool:
doc = getattr(client, "cimd_document", None)
return bool(doc) Try / catch
try:
await manager.validate_private_key_jwt(assertion, client, endpoint)
except ValueError as e:
if "must have CIMD document" in str(e):
await manager.reload_client_metadata(client.client_id)
raise Prevention
- Ensure the CIMD document is fetched and attached to the client before processing token requests
- Confirm client_id is a valid CIMD URL that resolves at registration time
- Only use private_key_jwt for clients actually registered via CIMD metadata
- Add a startup/start-of-flow check that every active CIMD client has a loaded document
When it happens
Trigger: `authenticate_request` reaches `validate_private_key_jwt` with a client whose `cimd_document` was never fetched, failed to load, or was set to None — e.g. the client_id's CIMD metadata retrieval failed earlier or the client is not a CIMD-registered client at all.
Common situations: Client is registered via a non-CIMD flow (standard dynamic/registered client) but sends private_key_jwt; the CIMD URL for the client_id is unreachable or invalid so the document was never loaded; the document cache was cleared and re-fetch failed.
Related errors
- CIMD document must have jwks_uri or jwks for private_key_jwt
- Invalid JWT assertion
- JWKS document contains no keys
- CIMD document must specify private_key_jwt auth method
- Invalid client_assertion_type: expected {JWT_BEARER_ASSERTIO
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/5dddd492afd172a1.
Report an issue: GitHub.