{"record":{"id":"31f9ab7b68b91d8e","repo":"PrefectHQ/fastmcp","slug":"invalid-client-assertion-type-expected-jwt-beare","errorCode":null,"errorMessage":"Invalid client_assertion_type: expected {JWT_BEARER_ASSERTION_TYPE}","messagePattern":"Invalid client_assertion_type: expected (.+?)","errorType":"http","errorClass":"AuthenticationError","httpStatus":401,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/auth/auth.py","lineNumber":277,"sourceCode":"        client_id = form_data.get(\"client_id\")\n\n        # If client_id is not in form data, delegate to SDK\n        # This handles client_secret_basic which sends credentials in Authorization header\n        if not client_id:\n            return await super().authenticate_request(request)\n\n        client = await self.provider.get_client(str(client_id))\n        if not client:\n            raise AuthenticationError(\"Invalid client_id\")\n\n        # Handle private_key_jwt authentication for CIMD clients\n        if client.token_endpoint_auth_method == \"private_key_jwt\":\n            # Validate assertion parameters\n            assertion_type = form_data.get(\"client_assertion_type\")\n            assertion = form_data.get(\"client_assertion\")\n\n            if assertion_type != JWT_BEARER_ASSERTION_TYPE:\n                raise AuthenticationError(\n                    f\"Invalid client_assertion_type: expected {JWT_BEARER_ASSERTION_TYPE}\"\n                )\n\n            if not assertion or not isinstance(assertion, str):\n                raise AuthenticationError(\"Missing client_assertion\")\n\n            # Validate the JWT assertion using CIMD manager\n            try:\n                await self._cimd_manager.validate_private_key_jwt(\n                    assertion=assertion,\n                    client=client,\n                    token_endpoint=self._token_endpoint_url,\n                )\n            except ValueError as e:\n                raise AuthenticationError(f\"Invalid client assertion: {e}\") from e\n\n            return client\n","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/auth/auth.py#L259-L295","documentation":"When a client authenticates with token_endpoint_auth_method == 'private_key_jwt', the token request must carry client_assertion_type equal to the JWT-bearer IETF value (urn:ietf:params:oauth:client-assertion-type:jwt-bearer). If the form field is missing or has any other value, AuthenticationError('Invalid client_assertion_type: expected ...') is raised.","triggerScenarios":"Token request with client_id in form data for a private_key_jwt client where form_data['client_assertion_type'] is absent or not 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer' (auth.py:276-279).","commonSituations":"Custom OAuth clients hand-rolling the token request and omitting the assertion_type field; libraries sending client_secret_post-style bodies while the server expects private_key_jwt; misconfigured client registered as private_key_jwt but actually using another flow.","solutions":["Send `client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer` in the token request form body.","Also include a signed `client_assertion` JWT (next check in the same flow) so the request passes subsequent validation.","If the client shouldn't use private_key_jwt, register/configure it with the intended auth method (e.g. client_secret_post).","Use a conformant OAuth client library instead of a hand-built token request."],"exampleFix":"// before\nrequests.post(token_url, data={\"client_id\": cid, \"client_assertion\": jwt})\n\n// after\nrequests.post(token_url, data={\n    \"client_id\": cid,\n    \"client_assertion\": jwt,\n    \"client_assertion_type\": \"urn:ietf:params:oauth:client-assertion-type:jwt-bearer\",\n})","handlingStrategy":"validation","validationCode":"JWT_BEARER = 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer'\nassert form['client_assertion_type'] == JWT_BEARER, 'invalid client_assertion_type'\nassert isinstance(form.get('client_assertion'), str) and form['client_assertion']","typeGuard":null,"tryCatchPattern":"# client side\nif response.status_code == 401 and response.json().get('error') == 'invalid_client':\n    logger.error('check client_assertion_type and client_assertion fields')","preventionTips":["Always send both client_assertion_type and client_assertion for private_key_jwt.","Use the exact IETF urn value — no abbreviations.","Prefer a maintained OAuth client library over hand-rolled token requests."],"tags":["oauth","jwt","private-key-jwt","protocol-violation"],"backgroundTag":"invalid-oauth-assertion","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}