PrefectHQ/fastmcp · error · ValueError
Invalid JWT format (expected 3 parts)
Error message
Invalid JWT format (expected 3 parts)
What it means
decode_jwt_header/decode_jwt_payload expect a JWT with exactly three dot-separated parts (header.payload.signature). Tokens that are opaque strings, access tokens in other formats, or truncated JWTs fail this check with a ValueError.
Source
Thrown at fastmcp_slim/fastmcp/utilities/auth.py:25
from typing import Any
def _decode_jwt_part(token: str, part_index: int) -> dict[str, Any]:
"""Decode a JWT part (header or payload) without signature verification.
Args:
token: JWT token string (header.payload.signature)
part_index: 0 for header, 1 for payload
Returns:
Decoded part as a dictionary
Raises:
ValueError: If token is not a valid JWT format
"""
parts = token.split(".")
if len(parts) != 3:
raise ValueError("Invalid JWT format (expected 3 parts)")
part_b64 = parts[part_index]
part_b64 += "=" * (-len(part_b64) % 4) # Add padding
return json.loads(base64.urlsafe_b64decode(part_b64))
def decode_jwt_header(token: str) -> dict[str, Any]:
"""Decode JWT header without signature verification.
Useful for extracting the key ID (kid) for JWKS lookup.
Args:
token: JWT token string (header.payload.signature)
Returns:
Decoded header as a dictionary
Raises:View on GitHub (pinned to 1f02114297)
Solutions
- Verify the token is a JWT (two dots, base64url segments) before decoding
- Decode the ID token instead of the access token when using OAuth providers
- Check provider settings to ensure JWTs are being issued (RS256/HS256 signed tokens)
Example fix
// before
header = decode_jwt_header(access_token)
// after
if access_token.count(".") == 3 - 1:
header = decode_jwt_header(access_token) Defensive patterns
Strategy: validation
Validate before calling
def looks_like_jwt(token: str) -> bool:
parts = token.split(".")
return len(parts) == 3 and all(parts) Type guard
def is_jwt(token: object) -> bool:
return isinstance(token, str) and token.count(".") == 2 Try / catch
try:
claims = decode_jwt_payload(token)
except ValueError as e:
if "Invalid JWT format" in str(e):
# token is opaque or truncated; fetch/verify the real JWT
...
else:
raise Prevention
- Confirm the provider issues JWT access tokens before decoding
- Decode ID tokens, not opaque access tokens
- Validate token shape with token.count(".") == 2 first
When it happens
Trigger: Passing a non-JWT token (e.g. an OAuth opaque access token or API key) to decode_jwt_header or decode_jwt_payload, or a JWT missing its signature part.
Common situations: Misconfiguring auth so an opaque provider token is treated as a JWT; copying a token partially; using ID-token decoding helpers on access tokens from providers like Auth0 or Google that are not JWTs.
Related errors
- Subclasses must implement verify_token
- MultiAuth requires at least a server or one verifier
- Failed to extract key ID from token: {e}
- Assertion must include exp claim
- Assertion is not yet valid (nbf in future)
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/944ed0cb2adbc8c4.
Report an issue: GitHub.