PrefectHQ/fastmcp · error · RuntimeError
Claim '{self.claim_name}' not found in access token. Availab
Error message
Claim '{self.claim_name}' not found in access token. Available claims: {list(token.claims.keys())} What it means
The Claim dependency found a valid access token, but token.claims.get(claim_name) returned None, so it raises this RuntimeError listing the claims that ARE present. FastMCP distinguishes this from the no-token case so you can tell an auth setup problem from a claim-name/schema mismatch. Note it also fires when the claim exists but its value is None or falsy-None, since only None triggers the branch.
Source
Thrown at fastmcp_slim/fastmcp/server/dependencies.py:1346
# --- Token Claim dependency ---
class _TokenClaim(Dependency[str]):
"""Dependency that extracts a specific claim from the access token."""
def __init__(self, claim_name: str):
self.claim_name = claim_name
async def __aenter__(self) -> str:
token = get_access_token()
if token is None:
raise RuntimeError(
f"No access token available. Cannot extract claim '{self.claim_name}'."
)
value = token.claims.get(self.claim_name)
if value is None:
raise RuntimeError(
f"Claim '{self.claim_name}' not found in access token. "
f"Available claims: {list(token.claims.keys())}"
)
return str(value)
async def __aexit__(
self,
exc_type: type[BaseException] | None,
exc_value: BaseException | None,
traceback: TracebackType | None,
) -> None:
pass
def TokenClaim(name: str) -> str:
"""Get a specific claim from the access token.
This dependency extracts a single claim value from the current access token.View on GitHub (pinned to 1f02114297)
Solutions
- Inspect the Available claims list in the message and correct the claim name in your Claim(...) call
- Decode the actual token (jwt.io or logs) to see the real claim keys your auth provider emits
- Configure the auth provider to include the needed claim in the access token (mappers/scope mappings)
- If the claim is optional, use get_access_token() and token.claims.get(name, default) instead
Example fix
// before
async def role() -> str:
with Claim("role") as r: # token only has 'roles'
return r
// after
async def role() -> str:
with Claim("roles") as r:
return r Defensive patterns
Strategy: fallback
Validate before calling
from fastmcp.server.dependencies import get_access_token
token = get_access_token()
value = token.claims.get('sub') if token else None
if value is None:
... # fallback or error before raising Type guard
from fastmcp.server.dependencies import get_access_token
def get_claim(name: str) -> str | None:
token = get_access_token()
v = token.claims.get(name) if token else None
return str(v) if v is not None else None Try / catch
try:
async with Claim('roles') as roles:
return roles.split()
except RuntimeError as e:
if 'not found in access token' in str(e):
logger.warning('claims available: check message for actual keys')
return [] Prevention
- Read the Available claims list in the message — it tells you the exact keys present
- Match claim names to your identity provider's actual token payload (decode the JWT)
- Configure provider claim mappings rather than renaming claims in code
- Prefer get_access_token().claims.get(name, default) for optional claims
When it happens
Trigger: Entering `with Claim("roles")` when the token's claims dict has no "roles" key; the auth provider issues tokens with different claim names (e.g. "scope" vs "scopes", OIDC "preferred_username" vs custom "username"); the claim value is literally null in the JWT payload.
Common situations: Switching identity providers (Auth0 → Keycloak) with different claim vocabularies; forgetting that ID token claims vs access token claims differ; typos in claim names; token templates/mappings not configured on the auth server.
Related errors
- No access token available. Cannot extract claim '{self.claim
- Assertion must include exp claim
- Assertion is not yet valid (nbf in future)
- Assertion iat is in the future
- Assertion lifetime too long (max {self.MAX_ASSERTION_LIFETIM
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/0b8770dda1626ff3.
Report an issue: GitHub.