PrefectHQ/fastmcp · error · ValueError
Unsupported JWK key type: {key_type!r}
Error message
Unsupported JWK key type: {key_type!r} What it means
A ValueError from _jwk_to_pem (fastmcp_slim/fastmcp/server/auth/cimd.py:48) when converting a JWK from a CIMD document's jwks into PEM for JWT signature verification and the key's 'kty' is neither 'RSA' nor 'EC'. Only RSA and EC asymmetric keys are supported; oct (symmetric) and OKP (Ed25519) keys are rejected.
Source
Thrown at fastmcp_slim/fastmcp/server/auth/cimd.py:54
SSRFFetchError,
ssrf_safe_fetch_response,
validate_url,
)
from fastmcp.utilities.logging import get_logger
if TYPE_CHECKING:
from fastmcp.server.auth.providers.jwt import JWTVerifier
logger = get_logger(__name__)
def _jwk_to_pem(key_data: dict[str, Any]) -> str:
key_type = key_data.get("kty")
if key_type == "RSA":
return jwk.import_key(key_data, "RSA").as_pem().decode("utf-8")
if key_type == "EC":
return jwk.import_key(key_data, "EC").as_pem().decode("utf-8")
raise ValueError(f"Unsupported JWK key type: {key_type!r}")
class CIMDDocument(BaseModel):
"""CIMD document per draft-parecki-oauth-client-id-metadata-document.
The client metadata document is a JSON document containing OAuth client
metadata. The client_id property MUST match the URL where this document
is hosted.
Key constraint: token_endpoint_auth_method MUST NOT use shared secrets
(client_secret_post, client_secret_basic, client_secret_jwt).
redirect_uris is required and must contain at least one entry.
"""
client_id: AnyHttpUrl = Field(
...,
description="Must match the URL where this document is hosted",View on GitHub (pinned to 1f02114297)
Solutions
- Publish an RSA or EC key in the CIMD document's jwks (kty exactly 'RSA' or 'EC', uppercase).
- Replace OKP/Ed25519 keys with ES256 (EC P-256) or RS256 (RSA) signing keys in the client.
- Check every jwks entry for a present, correctly-cased kty value.
- If you control the client, generate a new supported key pair and update the hosted CIMD document.
Example fix
// before
{"kty": "OKP", "crv": "Ed25519", "x": "..."}
// after
{"kty": "EC", "crv": "P-256", "x": "...", "y": "..."} Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED_KTY = {'RSA', 'EC'}
keys = cimd_doc.get('jwks', {}).get('keys', [])
for k in keys:
if k.get('kty') not in SUPPORTED_KTY:
raise ValueError(f"CIMD jwks key kty={k.get('kty')!r} unsupported; publish RSA or EC") Type guard
def is_supported_jwk(key: dict) -> bool:
return key.get('kty') in ('RSA', 'EC') Try / catch
try:
client = await cimd_manager.get_client(client_id)
except ValueError as e:
logger.error('CIMD key issue: %s', e)
raise HTTPException(401, 'invalid_client') from e Prevention
- Publish only RSA or EC keys (uppercase 'RSA'/'EC') in CIMD jwks documents.
- Avoid OKP (Ed25519) and oct keys for private_key_jwt client authentication.
- Validate the jwks JSON with a script before hosting the CIMD document.
- Never leave kty missing — every JWK requires it.
When it happens
Trigger: A CIMD document's jwks contains a key with kty='oct', kty='OKP', a missing kty field, or a misspelled value (e.g. lowercase 'rsa'); _extract_public_key_from_jwks selects that key while validating a private_key_jwt assertion.
Common situations: Clients publishing symmetric keys in their CIMD jwks (invalid for this flow); Ed25519 (OKP) signing keys not yet supported by this implementation; hand-written jwks JSON with a typo or a missing kty field.
Related errors
- Invalid client assertion: {e}
- CIMD document must have jwks_uri or jwks for private_key_jwt
- Invalid JWT assertion
- Invalid client_assertion_type: expected {JWT_BEARER_ASSERTIO
- Missing client_assertion
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/ceff000d53514a4b.
Report an issue: GitHub.