PrefectHQ/fastmcp · error · RuntimeError
EntraOBOToken requires an AzureProvider as the auth provider
Error message
EntraOBOToken requires an AzureProvider as the auth provider. Current provider: {type(server.auth).__name__} What it means
After obtaining the access token, EntraOBOToken locates the server's auth provider with _find_azure_provider to perform the OBO exchange. If the server's auth provider is not an AzureProvider (or doesn't wrap one), the OBO exchange can't be performed, so it raises RuntimeError naming the actual provider type.
Source
Thrown at fastmcp_slim/fastmcp/server/auth/providers/azure.py:858
def __init__(self, scopes: list[str]):
self.scopes = scopes
async def __aenter__(self) -> str:
_require_azure_identity("EntraOBOToken")
from fastmcp.server.dependencies import get_access_token, get_server
access_token = get_access_token()
if access_token is None:
raise RuntimeError(
"No access token available. Cannot perform OBO exchange."
)
server = get_server()
azure_provider = _find_azure_provider(server.auth)
if azure_provider is None:
raise RuntimeError(
"EntraOBOToken requires an AzureProvider as the auth provider. "
f"Current provider: {type(server.auth).__name__}"
)
credential = await azure_provider.get_obo_credential(
user_assertion=access_token.token,
)
result = await credential.get_token(*self.scopes)
return result.token
def EntraOBOToken(scopes: list[str]) -> str:
"""Exchange the user's Entra token for a downstream API token via OBO.
This dependency performs a Microsoft Entra On-Behalf-Of (OBO) token exchange,
allowing your MCP server to call downstream APIs (like Microsoft Graph) on
behalf of the authenticated user.View on GitHub (pinned to 1f02114297)
Solutions
- Set the server's auth to AzureProvider(...): FastMCP(..., auth=AzureProvider(...)).
- Remove or gate EntraOBOToken usage in tools when running against non-Azure auth.
- If you wrap AzureProvider in a custom provider, make it discoverable by _find_azure_provider or call azure_provider.get_obo_credential directly.
Example fix
// before mcp = FastMCP(name="app", auth=GitHubProvider(client_id=cid, client_secret=sec)) // after mcp = FastMCP(name="app", auth=AzureProvider(client_id=cid, client_secret=sec, tenant_id=tid))
Defensive patterns
Strategy: type-guard
Validate before calling
from fastmcp.server.auth.providers.azure import AzureProvider, _find_azure_provider
from fastmcp.server.dependencies import get_server
if _find_azure_provider(get_server().auth) is None:
raise RuntimeError("Server auth must be (or wrap) AzureProvider for EntraOBOToken") Type guard
def server_uses_azure(auth) -> bool:
from fastmcp.server.auth.providers.azure import _find_azure_provider
return _find_azure_provider(auth) is not None Try / catch
try:
async with EntraOBOToken(scopes=["api"]) as t:
...
except RuntimeError as e:
if "requires an AzureProvider" in str(e):
logger.error(f"Wrong auth provider configured: {e}")
raise Prevention
- Configure FastMCP(auth=AzureProvider(...)) wherever OBO tokens are used
- Assert the provider type at startup with a smoke check
- Search for EntraOBOToken usages when migrating auth providers
When it happens
Trigger: Using EntraOBOToken on a server whose auth is, e.g., JWTVerifier, GoogleProvider, GitHubProvider, or any non-Azure AuthProvider.
Common situations: Copy-pasting EntraOBOToken sample code into a project that uses a different identity provider; switching the server's auth provider during migration and leaving OBO token usage in tools; wrapping AzureProvider in a custom AuthProvider that _find_azure_provider doesn't recognize.
Related errors
- OBO token exchange requires either a client_secret or a subc
- AzureProvider requires at least one non-OIDC scope in requir
- tenant_name should be the short name without the .onmicrosof
- Azure AD B2C does not support the On-Behalf-Of (OBO) flow. U
- No access token available. Cannot perform OBO exchange.
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/df5d203a97d1dad9.
Report an issue: GitHub.