{"record":{"id":"fcdd0741a32c1558","repo":"PrefectHQ/fastmcp","slug":"failed-to-convert-jwk-to-pem-e","errorCode":null,"errorMessage":"Failed to convert JWK to PEM: {e}","messagePattern":"Failed to convert JWK to PEM: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/server/auth/cimd.py","lineNumber":700,"sourceCode":"            if kid and key.get(\"kid\") == kid:\n                matching_key = key\n                break\n\n        if not matching_key:\n            # If no kid match, try first key as fallback\n            if len(keys) == 1:\n                matching_key = keys[0]\n                self.logger.warning(\n                    \"No matching kid in JWKS, using single available key\"\n                )\n            else:\n                raise ValueError(f\"No matching key found for kid={kid} in JWKS\")\n\n        # Convert JWK to PEM\n        try:\n            return _jwk_to_pem(matching_key)\n        except (JoseError, TypeError, ValueError) as e:\n            raise ValueError(f\"Failed to convert JWK to PEM: {e}\") from e\n\n\nclass CIMDClientManager:\n    \"\"\"Manages all CIMD client operations for OAuth proxy.\n\n    This class encapsulates:\n    - CIMD client detection\n    - Document fetching and validation\n    - Synthetic OAuth client creation\n    - Private key JWT assertion validation\n\n    This allows the OAuth proxy to delegate all CIMD-specific logic to a\n    single, focused manager class.\n    \"\"\"\n\n    def __init__(\n        self,\n        enable_cimd: bool = True,","sourceCodeStart":682,"sourceCodeEnd":718,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/server/auth/cimd.py#L682-L718","documentation":"A matching JWK entry was found in the JWKS, but converting it to a PEM public key failed (`_jwk_to_pem` raised a jose error, TypeError, or ValueError). This means the JWK entry itself is malformed or of an unsupported type/curve.","triggerScenarios":"The selected JWK has missing/invalid fields (e.g. bad `n`/`e` base64url for RSA, unsupported `kty` or `crv`, truncated key material), causing the python-jose conversion to fail while extracting the public key in `_extract_public_key_from_jwks`.","commonSituations":"Hand-authored JWKS with copy-paste-corrupted base64url values; unsupported key type (EC curve not supported by the crypto backend, OKP/Ed25519 keys); a JWK containing a private-only or symmetric (`kty: oct`) key where an RSA/EC public key is required.","solutions":["Regenerate the JWK entry with a proper tool so base64url components are complete and correct (e.g. publish the RSA `n`/`e` from the actual signing key)","Use a supported key type — RSA or an EC curve supported by the installed cryptography backend","Ensure the JWKS entry is a public asymmetric key (not `kty: oct`), including public components","Compare the JWKS entry against the issuer's canonical published JWKS and replace the malformed entry"],"exampleFix":"// before (truncated modulus)\n{\"kty\": \"RSA\", \"kid\": \"key-1\", \"n\": \"abc\", \"e\": \"AQAB\"}\n// after (full base64url modulus)\n{\"kty\": \"RSA\", \"kid\": \"key-1\", \"n\": \"0vx7agoebGcQS...full modulus...\", \"e\": \"AQAB\"}","handlingStrategy":"validation","validationCode":"from jose import jwt as jose_jwt\nfrom jose.exceptions import JOSEError\nfor k in jwks[\"keys\"]:\n    try:\n        jose_jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(k))\n    except (JOSEError, ValueError) as e:\n        raise ValueError(f\"Malformed JWK {k.get('kid')}: {e}\")","typeGuard":"def is_wellformed_rsa_jwk(k: dict) -> bool:\n    return k.get(\"kty\") == \"RSA\" and bool(k.get(\"n\")) and bool(k.get(\"e\"))","tryCatchPattern":"try:\n    key = extract_public_key(jwks, kid)\nexcept ValueError as e:\n    if \"Failed to convert JWK to PEM\" in str(e):\n        logger.error(\"JWKS entry malformed; refetch/repair JWKS for kid=%s\", kid)\n    raise","preventionTips":["Generate JWKS entries with a maintained tool (e.g. authlib, jose) rather than hand-writing base64url values","Only publish public asymmetric keys (RSA/EC), never `kty: oct` symmetric keys in an assertion JWKS","Validate the full JWKS round-trips to PEM at deployment/startup time","Check that key components are complete un-padded base64url strings"],"tags":["oauth","jwks","key-format","cryptography"],"backgroundTag":"jwk-to-pem-conversion-failed","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}