PrefectHQ/fastmcp · error · ValueError
tenant_name should be the short name without the .onmicrosof
Error message
tenant_name should be the short name without the .onmicrosoft.com suffix (e.g. 'mytenant'), got {tenant_name!r} What it means
AzureProvider.from_b2c builds B2C endpoints from tenant_name as https://{tenant_name}.b2clogin.com and the issuer as https://{tenant_name}.onmicrosoft.com/{client_id}. If you pass a tenant_name that already contains '.onmicrosoft.com', the constructed URLs would be malformed (double suffix), so the classmethod rejects it with ValueError.
Source
Thrown at fastmcp_slim/fastmcp/server/auth/providers/azure.py:343
(e.g. `"mytenant"`).
policy_name: User-flow or custom-policy name
(e.g. `"B2C_1_susi"`).
client_id: Application (client) ID from the B2C app registration.
client_secret: Client secret from the B2C app registration.
required_scopes: Custom API scope names without prefix
(e.g. `["mcp-access"]`).
base_url: Public base URL of this server.
custom_domain: Custom domain for the B2C authority
(e.g. `"auth.mycompany.com"`). Defaults to
`{tenant_name}.b2clogin.com`.
identifier_uri: Application ID URI. Defaults to
`https://{tenant_name}.onmicrosoft.com/{client_id}`.
token_issuer: Expected `iss` claim. `None` (default) disables
issuer validation.
**kwargs: Forwarded to `AzureProvider.__init__`.
"""
if ".onmicrosoft.com" in tenant_name:
raise ValueError(
f"tenant_name should be the short name without the "
f".onmicrosoft.com suffix (e.g. 'mytenant'), got {tenant_name!r}"
)
if custom_domain is not None:
custom_domain = (
custom_domain.removeprefix("https://")
.removeprefix("http://")
.rstrip("/")
)
authority = custom_domain or f"{tenant_name}.b2clogin.com"
tenant_path = f"{tenant_name}.onmicrosoft.com/{policy_name}"
uri = identifier_uri or f"https://{tenant_name}.onmicrosoft.com/{client_id}"
provider = cls(
client_id=client_id,
client_secret=client_secret,View on GitHub (pinned to 1f02114297)
Solutions
- Strip the .onmicrosoft.com suffix: pass 'mytenant' instead of 'mytenant.onmicrosoft.com'.
- If you have the full domain, split it: tenant_name = domain.split('.onmicrosoft.com')[0].
- Use a custom_domain argument if your B2C tenant uses a custom login domain.
Example fix
// before AzureProvider.from_b2c(tenant_name="mytenant.onmicrosoft.com", client_id=cid) // after AzureProvider.from_b2c(tenant_name="mytenant", client_id=cid)
Defensive patterns
Strategy: validation
Validate before calling
def normalize_b2c_tenant(name: str) -> str:
if ".onmicrosoft.com" in name:
raise ValueError("Pass the short tenant name without .onmicrosoft.com")
return name Type guard
def is_short_tenant_name(name: str) -> bool:
return bool(name) and ".onmicrosoft.com" not in name and "/" not in name Try / catch
try:
provider = AzureProvider.from_b2c(tenant_name=tenant, client_id=cid)
except ValueError as e:
if ".onmicrosoft.com" in str(e):
provider = AzureProvider.from_b2c(tenant_name=tenant.split(".")[0], client_id=cid)
else:
raise Prevention
- Store the short tenant name in config, not the full domain
- Normalize env-provided values: tenant.split('.onmicrosoft.com')[0]
When it happens
Trigger: Calling AzureProvider.from_b2c(tenant_name='mytenant.onmicrosoft.com', ...) — the check `'.onmicrosoft.com' in tenant_name` fires for any such value.
Common situations: Copy-pasting the full tenant domain from the Azure portal or from a token's issuer claim instead of the short B2C tenant name; configuring from environment variables that hold the full domain.
Related errors
- AzureProvider requires at least one non-OIDC scope in requir
- Azure AD B2C does not support the On-Behalf-Of (OBO) flow. U
- OBO token exchange requires either a client_secret or a subc
- EntraOBOToken requires an AzureProvider as the auth provider
- ClientGroup requires at least one client
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/5a84023c3b2711ae.
Report an issue: GitHub.