BerriAI/litellm · error · ValueError
MCPJWTSigner: token_introspection_endpoint is required for o
Error message
MCPJWTSigner: token_introspection_endpoint is required for opaque token verification but is not configured.
What it means
Opaque (non-JWT) bearer tokens cannot be verified against a JWKS, so MCPJWTSigner verifies them via RFC 7662 token introspection. _introspect_opaque_token raises ValueError when it is reached but token_introspection_endpoint was never configured - the verification path is impossible to complete.
Source
Thrown at litellm/proxy/guardrails/guardrail_hooks/mcp_jwt_signer/mcp_jwt_signer.py:484
decode_kwargs["audience"] = self.verify_audience
else:
decode_options["verify_aud"] = False
if self.verify_issuer:
decode_kwargs["issuer"] = self.verify_issuer
payload: Final[dict[str, object]] = jwt.decode(raw_token, signing_jwk.key, **decode_kwargs)
return payload
async def _introspect_opaque_token(self, token: str) -> dict[str, object]:
"""
Perform RFC 7662 token introspection for opaque (non-JWT) tokens.
Returns the introspection response dict. Raises on HTTP error or
inactive token.
"""
if not self.token_introspection_endpoint:
raise ValueError(
"MCPJWTSigner: token_introspection_endpoint is required for "
"opaque token verification but is not configured."
)
from litellm.llms.custom_httpx.http_handler import (
get_async_httpx_client,
httpxSpecialProvider,
)
client: Final = get_async_httpx_client(llm_provider=httpxSpecialProvider.Oauth2Check)
resp: Final = await client.post(
self.token_introspection_endpoint,
data={"token": token},
headers={"Accept": "application/json"},
)
resp.raise_for_status()
result: Final[dict[str, object]] = resp.json()
if not result.get("active", False):View on GitHub (pinned to 77b7c6c40c)
Solutions
- Configure token_introspection_endpoint in the guardrail litellm_params, pointing at the IdP's RFC 7662 introspection endpoint
- Alternatively send JWT access tokens from clients so the JWKS path is used
- If opaque tokens need not be verified, remove access_token_discovery_uri - the signer then logs a warning and proceeds without verification
Example fix
# before - opaque tokens arrive but no introspection endpoint litellm_params: access_token_discovery_uri: https://idp.example.com/.well-known/openid-configuration # after - RFC 7662 introspection configured litellm_params: access_token_discovery_uri: https://idp.example.com/.well-known/openid-configuration token_introspection_endpoint: https://idp.example.com/oauth2/introspect
Defensive patterns
Strategy: validation
Validate before calling
lp = guardrail_entry["litellm_params"]
if lp.get("access_token_discovery_uri"):
# opaque bearer tokens will need RFC 7662 introspection
assert lp.get("token_introspection_endpoint") or clients_send_jwt_only, (
"token_introspection_endpoint required when opaque tokens may arrive"
) Prevention
- Decide up front whether clients send JWTs or opaque tokens; if opaque, configure token_introspection_endpoint with the IdP
- Decode a sample client token (count the dot-separated segments) to confirm which verification path you need
When it happens
Trigger: access_token_discovery_uri is set, an incoming request carries an opaque bearer token (not three dot-separated base64 segments), and the guardrail's litellm_params lack token_introspection_endpoint.
Common situations: Mixing JWT and opaque-token clients (legacy API keys, reference tokens from IdentityServer); enabling incoming verification for JWTs and then an opaque-token client arrives; introspection endpoint configured under a typo'd key so it reads as None.
Related errors
- MCPJWTSigner guardrail requires a guardrail_name
- MCPJWTSigner guardrail '{guardrail_name}' has mode='{mode}'
- MCPJWTSigner: ttl_seconds must be > 0, got {resolved_ttl}
- MCPJWTSigner: incoming token verification failed: {exc}
- invalid_request
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/5696323dfdb6d1e2.
Report an issue: GitHub.