{"record":{"id":"b171d1142b30005b","repo":"PrefectHQ/fastmcp","slug":"unsupported-grant-type","errorCode":"unsupported_grant_type","errorMessage":"unsupported_grant_type: The JWT bearer grant is not supported by this authorization server","messagePattern":"unsupported_grant_type: The JWT bearer grant is not supported by this authorization server","errorType":"error_code","errorClass":"TokenError","httpStatus":400,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/auth/oauth_proxy/proxy.py","lineNumber":1530,"sourceCode":"        client: OAuthClientInformationFull,\n        params: IdentityAssertionParams,\n    ) -> OAuthToken:\n        \"\"\"Exchange a SEP-990 ID-JAG for a short-lived FastMCP access token.\n\n        Validates the ID-JAG against the configured trusted issuers (signature,\n        `iss`, `aud`, `exp`, `typ`, `sub`, and `jti` replay), then mints a\n        self-contained FastMCP access token carrying the asserted subject. No\n        refresh token is issued — the client re-exchanges a fresh assertion.\n\n        Raises:\n            TokenError: ``invalid_grant`` if the assertion is rejected, or\n                ``unsupported_grant_type`` if identity assertion is not configured.\n        \"\"\"\n        if (\n            self._identity_assertion is None\n            or self._identity_assertion_validator is None\n        ):\n            raise TokenError(\n                \"unsupported_grant_type\",\n                \"The JWT bearer grant is not supported by this authorization server\",\n            )\n\n        # RFC 8707: when the request names a resource, it must be this server —\n        # the same invariant (and the same skip-when-unconfigured behavior)\n        # authorize() enforces for authorization requests.\n        if params.resource and self._resource_url:\n            server_url = str(self._resource_url)\n            client_url = str(params.resource)\n            if server_url_has_query(server_url):\n                # Server has query params - require exact match for security\n                resource_matches = client_url.rstrip(\"/\") == server_url.rstrip(\"/\")\n            else:\n                resource_matches = normalize_resource_url(\n                    client_url\n                ) == normalize_resource_url(server_url)\n            if not resource_matches:","sourceCodeStart":1512,"sourceCodeEnd":1548,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/auth/oauth_proxy/proxy.py#L1512-L1548","documentation":"Raised by exchange_identity_assertion when a client presents a JWT bearer grant (ID-JAG, RFC 7523-style identity assertion) but the proxy has no IdentityAssertion provider and validator configured. Identity assertion is an opt-in capability; without configuration the server must reject the grant type per spec with 'unsupported_grant_type'.","triggerScenarios":"POST /token with grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer (handled via _maybe_handle_id_jag) against an OAuthProxy instance constructed without identity_assertion/validator arguments.","commonSituations":"Client assumes the server supports ID-JAG but the server was never configured for it; version mismatch where the client was built against an ID-JAG-enabled deployment and points at a plain proxy; copy-pasted client config enabling jwt-bearer grants unconditionally.","solutions":["Either stop sending the JWT bearer grant and use the standard authorization_code flow.","Or configure the proxy with an identity assertion provider and validator so the grant type is supported.","Verify you are pointing the client at the correct server deployment (one with ID-JAG enabled).","Check the server's FastMCP version/config to confirm identity assertion support is enabled."],"exampleFix":"# before: plain proxy, client sends jwt-bearer grant\nproxy = OAuthProxy(upstream_authorization_endpoint=..., token_endpoint=...)\n# after: enable identity assertion support\nproxy = OAuthProxy(\n    ...,\n    identity_assertion=my_assertion_provider,\n    identity_assertion_validator=my_validator,\n)","handlingStrategy":"fallback","validationCode":"// check server capability before attempting jwt-bearer grant\nconst supportsIdJag = serverConfig.identityAssertion !== undefined;\nif (!supportsIdJag) useAuthorizationCodeFlow();","typeGuard":null,"tryCatchPattern":"try {\n  await idJagExchange(assertion);\n} catch (e) {\n  if (e.code === \"unsupported_grant_type\") {\n    await authorizationCodeFlow(); // fallback\n  } else throw e;\n}","preventionTips":["Confirm the deployment has identity assertion configured before sending jwt-bearer grants","Feature-detect or read server metadata for supported grant types","Keep client and server deployment configs in sync"],"tags":["oauth","id-jag","jwt-bearer","unsupported-grant-type"],"backgroundTag":"unsupported-grant-type","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}