crewAIInc/crewAI · error · HTTPException

Missing required claim: {e.claim}

Error message

Missing required claim: {e.claim}

What it means

Raised by OIDCAuth.authenticate() when jwt.decode() throws MissingRequiredClaimError: the token omits a claim that validation requires (typically `exp`, `iat`, or `aud` when audience checking is enabled). The missing claim name is interpolated into the HTTP 401 detail. It logs reason='missing_claim' with the specific claim at debug level.

Source

Thrown at lib/crewai/src/crewai/a2a/auth/server_schemes.py:333

            raise HTTPException(
                status_code=HTTP_401_UNAUTHORIZED,
                detail="Invalid token audience",
            ) from None
        except jwt.InvalidIssuerError:
            logger.debug(
                "OIDC authentication failed",
                extra={"reason": "invalid_issuer", "scheme": "oidc"},
            )
            raise HTTPException(
                status_code=HTTP_401_UNAUTHORIZED,
                detail="Invalid token issuer",
            ) from None
        except jwt.MissingRequiredClaimError as e:
            logger.debug(
                "OIDC authentication failed",
                extra={"reason": "missing_claim", "claim": e.claim, "scheme": "oidc"},
            )
            raise HTTPException(
                status_code=HTTP_401_UNAUTHORIZED,
                detail=f"Missing required claim: {e.claim}",
            ) from None
        except jwt.PyJWKClientError as e:
            logger.error(
                "OIDC authentication failed",
                extra={
                    "reason": "jwks_client_error",
                    "error": str(e),
                    "scheme": "oidc",
                },
            )
            raise HTTPException(
                status_code=HTTP_503_SERVICE_UNAVAILABLE,
                detail="Unable to fetch signing keys",
            ) from None
        except jwt.InvalidTokenError as e:
            logger.debug(

View on GitHub (pinned to 754d7323be)

Solutions

  1. Decode the token without verification and confirm which claim is absent; the detail message names it.
  2. Ensure the client requests the token type/scopes that make the IdP include the missing claim (e.g. pass audience so `aud` is present).
  3. If you generate tokens yourself for tests, include exp, iat, iss, and aud.
  4. Do not relax validation by removing required claims unless you accept the security trade-off.

Example fix

# before (test token missing standard claims)
import jwt
tok = jwt.encode({"sub": "user1"}, key, algorithm="RS256")  # 401 Missing required claim: exp

# after
import time
tok = jwt.encode(
    {"sub": "user1", "iss": "https://idp", "aud": "my-api", "iat": int(time.time()), "exp": int(time.time()) + 3600},
    key, algorithm="RS256",
)
Defensive patterns

Strategy: validation

Validate before calling

import jwt

REQUIRED = {"exp", "iat", "iss", "aud"}
claims = jwt.decode(access_token, options={"verify_signature": False})
missing = REQUIRED - claims.keys()
assert not missing, f"token missing required claims: {sorted(missing)}"

Try / catch

try:
    await scheme.authenticate(token)
except HTTPException as e:
    if e.status_code == 401 and e.detail.startswith("Missing required claim:"):
        claim = e.detail.rsplit(":", 1)[1].strip()
        # fix token issuance so `claim` is present, then retry

Prevention

When it happens

Trigger: A JWT signed by a valid key but lacking `aud` because the client requested a token without an audience; hand-crafted or legacy tokens missing `exp`/`iat`; opaque or malformed tokens that parse but carry an incomplete claim set.

Common situations: IdP configured to omit audience for certain client credentials flows; testing with tokens generated by ad-hoc scripts (e.g. jwt.encode({'sub':'x'}, ...) without standard claims); switching token types (ID token vs access token) where claim sets differ.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/aad48614f296bb0a. Report an issue: GitHub.