PrefectHQ/fastmcp · error · ValueError
Unsupported algorithm {v!r} for identity assertion: trusted
Error message
Unsupported algorithm {v!r} for identity assertion: trusted issuers are verified via JWKS, so algorithm must be one of {supported} What it means
The optional global `algorithm` for identity assertion must be one of the asymmetric JWS algorithms that JWTVerifier supports (via JWKS). HS* symmetric algorithms and unknown names are rejected at config time so they fail as a clean configuration error instead of a 500 on the first token exchange.
Source
Thrown at fastmcp_slim/fastmcp/server/auth/identity_assertion.py:162
def _validate_trusted_issuers(cls, v: list[str]) -> list[str]:
if not v:
raise ValueError("identity_assertion.trusted_issuers must not be empty")
for issuer in v:
if not issuer or not issuer.strip():
raise ValueError("trusted_issuers entries must be non-empty strings")
return v
@field_validator("algorithm")
@classmethod
def _validate_algorithm(cls, v: str | None) -> str | None:
# Trusted issuers are verified via JWKS (public keys only), so the
# algorithm must be one of the asymmetric JWS algorithms JWTVerifier
# actually supports — HS* (shared-secret) has no JWKS equivalent, and
# anything else (EdDSA, or a typo like RS999) would otherwise surface
# as a 500 on the first exchange instead of a clean config error now.
if v is not None and v not in SUPPORTED_ASSERTION_ALGORITHMS:
supported = ", ".join(sorted(SUPPORTED_ASSERTION_ALGORITHMS))
raise ValueError(
f"Unsupported algorithm {v!r} for identity assertion: trusted "
f"issuers are verified via JWKS, so algorithm must be one of "
f"{supported}"
)
return v
@field_validator("algorithms")
@classmethod
def _validate_algorithms(cls, v: dict[str, str] | None) -> dict[str, str] | None:
if v is not None:
for issuer, algorithm in v.items():
if algorithm not in SUPPORTED_ASSERTION_ALGORITHMS:
supported = ", ".join(sorted(SUPPORTED_ASSERTION_ALGORITHMS))
raise ValueError(
f"Unsupported algorithm {algorithm!r} for issuer "
f"{issuer!r}: must be one of {supported}"
)
return vView on GitHub (pinned to 1f02114297)
Solutions
- Set `algorithm` to a supported asymmetric algorithm (e.g. "RS256", "ES256") — see the sorted list in the error message
- Remove the `algorithm` setting to use the default behavior (algorithms derived per issuer)
- If you need HS*, that algorithm is not supported for JWKS-verified trusted issuers — switch the issuer to asymmetric keys
Example fix
# before IdentityAssertionSettings(trusted_issuers=[...], algorithm="HS256") # after IdentityAssertionSettings(trusted_issuers=[...], algorithm="RS256")
Defensive patterns
Strategy: validation
Validate before calling
SUPPORTED = {"RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "PS256", "PS384", "PS512"}
if algorithm is not None and algorithm not in SUPPORTED:
raise ValueError(f"algorithm {algorithm!r} unsupported for JWKS verification") Type guard
def is_supported_algorithm(alg: str | None) -> bool:
return alg is None or alg in SUPPORTED_ASSERTION_ALGORITHMS Try / catch
try:
settings = IdentityAssertionSettings(algorithm=alg)
except ValidationError as e:
logger.error("Invalid identity assertion algorithm %r: %s", alg, e)
raise SystemExit(1) Prevention
- Only use asymmetric algorithms (RS*/ES*/PS*) with JWKS-based verification
- Avoid copy-pasting HS* settings from shared-secret JWT configurations
- Import SUPPORTED_ASSERTION_ALGORITHMS from the library instead of hardcoding names
- Validate algorithm names at config load, not at first request
When it happens
Trigger: Setting `algorithm="HS256"` (shared-secret — no JWKS equivalent), `algorithm="EdDSA"` (unsupported here), or a typo like `algorithm="RS999"` triggers `_validate_algorithm` during model validation.
Common situations: Copy-pasting a symmetric algorithm from a client-secret JWT setup; typos in algorithm names; migrating config from a shared-secret verifier to JWKS-based trusted-issuer verification without changing the algorithm.
Related errors
- Unsupported algorithm {algorithm!r} for issuer {issuer!r}: m
- Invalid URL: {url}
- At least one of 'tools', 'include_tags', or 'exclude_tags' i
- No MCP servers defined in the config: {file_path}
- CIMD document must have jwks_uri or jwks for private_key_jwt
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/dbbbba47618aaf71.
Report an issue: GitHub.