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.
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
- CIMD document must specify private_key_jwt auth method
- Invalid JWT assertion
- JWKS document contains no keys
- Assertion lifetime too long
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/5dddd492afd172a1.
Report an issue: GitHub.
Appendix: 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)