PrefectHQ/fastmcp · error · ValueError
AzureProvider requires at least one non-OIDC scope in requir
Error message
AzureProvider requires at least one non-OIDC scope in required_scopes (e.g., 'read', 'write'). OIDC scopes like 'openid', 'profile', 'email', and 'offline_access' are not included in Azure access token claims and cannot be used for scope enforcement.
What it means
AzureProvider enforces scopes against claims embedded in the Azure access token. OIDC scopes (openid, profile, email, offline_access) are never included in those token claims, so if required_scopes contains only OIDC scopes there is nothing enforceable — every request would fail scope checks. The constructor therefore rejects such configurations with ValueError.
Source
Thrown at fastmcp_slim/fastmcp/server/auth/providers/azure.py:236
self._obo_supported = True
# Apply defaults
self.identifier_uri = identifier_uri or f"api://{client_id}"
self.additional_authorize_scopes: list[str] = parsed_additional_scopes
# Always validate tokens against the app's API client ID using JWT
issuer = token_issuer or f"https://{base_authority}/{tenant_id}/v2.0"
jwks_uri = f"https://{base_authority}/{tenant_id}/discovery/v2.0/keys"
# Azure access tokens only include custom API scopes in the `scp` claim,
# NOT standard OIDC scopes (openid, profile, email, offline_access).
# Filter out OIDC scopes from validation - they'll still be sent to Azure
# during authorization (handled by _prefix_scopes_for_azure).
validation_scopes = [
s for s in (parsed_required_scopes or []) if s not in OIDC_SCOPES
]
if not validation_scopes:
raise ValueError(
"AzureProvider requires at least one non-OIDC scope in "
"required_scopes (e.g., 'read', 'write'). OIDC scopes like "
"'openid', 'profile', 'email', and 'offline_access' are not "
"included in Azure access token claims and cannot be used for "
"scope enforcement."
)
token_verifier = JWTVerifier(
jwks_uri=jwks_uri,
issuer=issuer,
audience=[client_id, self.identifier_uri],
algorithm="RS256",
required_scopes=validation_scopes, # Only validate non-OIDC scopes
http_client=http_client,
)
# Build Azure OAuth endpoints with tenant
authorization_endpoint = (View on GitHub (pinned to 1f02114297)
Solutions
- Add at least one application-defined scope (e.g. 'read', 'write', or an api://... scope exposed by your app) to required_scopes.
- If you only want OIDC scopes sent during login, remove required_scopes entirely — OIDC scopes are still sent to Azure via _prefix_scopes_for_azure without being enforced.
- Enforce OIDC scope presence with a custom token verifier if truly needed, not via required_scopes.
Example fix
// before AzureProvider(client_id=cid, client_secret=sec, required_scopes=["openid", "profile"]) // after AzureProvider(client_id=cid, client_secret=sec, required_scopes=["read", "write"])
Defensive patterns
Strategy: validation
Validate before calling
OIDC_SCOPES = {"openid", "profile", "email", "offline_access"}
if required_scopes and not (set(required_scopes) - OIDC_SCOPES):
raise ValueError("AzureProvider required_scopes needs at least one non-OIDC scope") Type guard
def has_enforceable_scopes(scopes: list[str] | None) -> bool:
oidc = {"openid", "profile", "email", "offline_access"}
return bool(scopes) and bool(set(scopes) - oidc) Try / catch
try:
provider = AzureProvider(client_id=cid, client_secret=sec, required_scopes=scopes)
except ValueError as e:
if "non-OIDC scope" in str(e):
provider = AzureProvider(client_id=cid, client_secret=sec, required_scopes=[*scopes, "read"])
else:
raise Prevention
- Keep authorization-request scopes separate from enforcement scopes in config
- Document app-defined scopes (api://... / read / write) as the source for required_scopes
When it happens
Trigger: AzureProvider(client_id=..., client_secret=..., required_scopes=["openid", "profile"]) — i.e. parsed required_scopes minus OIDC_SCOPES yields an empty list.
Common situations: Reusing a required_scopes list meant for the authorization request (openid/profile) as the enforcement list; copying Google/GenericOAuth examples where OIDC scopes are legitimate requirements; assuming Azure validates OIDC scopes in tokens.
Related errors
- Cannot specify 'required_scopes' when providing a custom tok
- Missing required OIDC endpoints
- tenant_name should be the short name without the .onmicrosof
- OBO token exchange requires either a client_secret or a subc
- EntraOBOToken requires an AzureProvider as the auth provider
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/776479cb53288242.
Report an issue: GitHub.