{"record":{"id":"5dddd492afd172a1","repo":"PrefectHQ/fastmcp","slug":"client-must-have-cimd-document-for-private-key-jwt","errorCode":null,"errorMessage":"Client must have CIMD document for private_key_jwt","messagePattern":"Client must have CIMD document for private_key_jwt","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/auth/cimd.py","lineNumber":817,"sourceCode":"        assertion: str,\n        client,  # OAuthProxyClient, untyped to avoid circular import\n        token_endpoint: str,\n    ) -> bool:\n        \"\"\"Validate JWT assertion for private_key_jwt auth.\n\n        Args:\n            assertion: JWT assertion string from client\n            client: OAuth proxy client (must have cimd_document)\n            token_endpoint: Token endpoint URL for aud validation\n\n        Returns:\n            True if assertion is valid\n\n        Raises:\n            ValueError: If client doesn't have CIMD document or validation fails\n        \"\"\"\n        if not hasattr(client, \"cimd_document\") or not client.cimd_document:\n            raise ValueError(\"Client must have CIMD document for private_key_jwt\")\n\n        cimd_doc = client.cimd_document\n        if cimd_doc.token_endpoint_auth_method != \"private_key_jwt\":\n            raise ValueError(\"CIMD document must specify private_key_jwt auth method\")\n\n        return await self._assertion_validator.validate_assertion(\n            assertion, client.client_id, token_endpoint, cimd_doc\n        )\n","sourceCodeStart":799,"sourceCodeEnd":826,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/auth/cimd.py#L799-L826","documentation":"`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.","triggerScenarios":"`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.","commonSituations":"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.","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"],"exampleFix":"# before: client without loaded metadata sending private_key_jwt\n# after: point client_id at a valid CIMD document\nclient_id = \"https://client.example.com/client-metadata.json\"  # must fetch and expose cimd_document","handlingStrategy":"validation","validationCode":"if not getattr(client, \"cimd_document\", None):\n    raise RuntimeError(\"Client CIMD document not loaded; cannot use private_key_jwt\")","typeGuard":"def has_cimd_document(client) -> bool:\n    doc = getattr(client, \"cimd_document\", None)\n    return bool(doc)","tryCatchPattern":"try:\n    await manager.validate_private_key_jwt(assertion, client, endpoint)\nexcept ValueError as e:\n    if \"must have CIMD document\" in str(e):\n        await manager.reload_client_metadata(client.client_id)\n    raise","preventionTips":["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"],"tags":["oauth","cimd","private-key-jwt","client-metadata"],"backgroundTag":"missing-client-metadata","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}