PrefectHQ/fastmcp · error · ValueError
Cannot specify 'required_scopes' when providing a custom tok
Error message
Cannot specify 'required_scopes' when providing a custom token_verifier. Configure required scopes on your token verifier instead.
What it means
OIDCProxy accepts a custom token_verifier to control token validation. When one is supplied, the proxy delegates all validation (including which algorithm to use and which scopes are required) to that verifier, so passing 'algorithm' or 'required_scopes' to the constructor would be contradictory/ignored. The library raises ValueError at construction time to force you to configure these on your verifier instead.
Source
Thrown at fastmcp_slim/fastmcp/server/auth/oidc_proxy.py:373
if not client_secret and not jwt_signing_key:
raise ValueError(
"Either client_secret or jwt_signing_key must be provided. "
"jwt_signing_key is required when client_secret is omitted "
"(e.g., for PKCE public clients)."
)
if not base_url:
raise ValueError("Missing required base URL")
# Validate that verifier-specific parameters are not used with custom verifier
if token_verifier is not None:
if algorithm is not None:
raise ValueError(
"Cannot specify 'algorithm' when providing a custom token_verifier. "
"Configure the algorithm on your token verifier instead."
)
if required_scopes is not None:
raise ValueError(
"Cannot specify 'required_scopes' when providing a custom token_verifier. "
"Configure required scopes on your token verifier instead."
)
if isinstance(config_url, str):
config_url = AnyHttpUrl(config_url)
self.oidc_config = self.get_oidc_configuration(
config_url, strict, timeout_seconds
)
if (
not self.oidc_config.authorization_endpoint
or not self.oidc_config.token_endpoint
):
logger.debug(f"Invalid OIDC Configuration: {self.oidc_config}")
raise ValueError("Missing required OIDC endpoints")
revocation_endpoint = (View on GitHub (pinned to 1f02114297)
Solutions
- Remove the required_scopes (and algorithm) arguments from the OIDCProxy constructor.
- Implement required-scope checking inside your custom token verifier (e.g. in verify_token, check token.scope/claims['scp'] and raise TokenVerifier error if scopes missing).
- If you don't need custom verification, drop token_verifier and let the proxy use required_scopes directly.
Example fix
// before
proxy = OIDCProxy(config_url=url, client_id=cid, token_verifier=MyVerifier(), required_scopes=["read"])
// after
class MyVerifier(TokenVerifier):
required_scopes = {"read"}
def verify_token(self, token):
... # enforce scopes here
proxy = OIDCProxy(config_url=url, client_id=cid, token_verifier=MyVerifier()) Defensive patterns
Strategy: validation
Validate before calling
def check_oidc_proxy_kwargs(kwargs):
if kwargs.get("token_verifier") is not None and (kwargs.get("required_scopes") or kwargs.get("algorithm")):
raise ValueError("required_scopes/algorithm must be configured on the custom token_verifier") Type guard
def has_custom_verifier(proxy_kwargs: dict) -> bool:
return proxy_kwargs.get("token_verifier") is not None Try / catch
try:
proxy = OIDCProxy(**kwargs)
except ValueError as e:
if "token_verifier" in str(e):
kwargs = {k: v for k, v in kwargs.items() if k not in ("required_scopes", "algorithm")}
proxy = OIDCProxy(**kwargs)
else:
raise Prevention
- Centralize scope/algorithm policy inside your TokenVerifier subclass
- Never mix token_verifier with proxy-level validation kwargs in factory functions
When it happens
Trigger: Constructing OIDCProxy with both a token_verifier argument and either required_scopes='...' (or algorithm='...') — e.g. OIDCProxy(config_url=..., client_id=..., token_verifier=MyVerifier(), required_scopes=['read']).
Common situations: Migrating from JWTVerifier/proxy-managed verification to a custom verifier while keeping the old constructor kwargs; copy-pasting example code that sets required_scopes and then adding a custom verifier for signature checks.
Related errors
- Missing required OIDC endpoints
- AzureProvider requires at least one non-OIDC scope in requir
- Could not extract project_id from config_url: {issuer_url}
- OAuth provider has no server URL. Either pass mcp_url to OAu
- OAuth server rejected the static client credentials. Verify
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/e54ce92b16a07617.
Report an issue: GitHub.