{"record":{"id":"aad48614f296bb0a","repo":"crewAIInc/crewAI","slug":"missing-required-claim-e-claim","errorCode":null,"errorMessage":"Missing required claim: {e.claim}","messagePattern":"Missing required claim: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":401,"severity":"error","filePath":"lib/crewai/src/crewai/a2a/auth/server_schemes.py","lineNumber":333,"sourceCode":"            raise HTTPException(\n                status_code=HTTP_401_UNAUTHORIZED,\n                detail=\"Invalid token audience\",\n            ) from None\n        except jwt.InvalidIssuerError:\n            logger.debug(\n                \"OIDC authentication failed\",\n                extra={\"reason\": \"invalid_issuer\", \"scheme\": \"oidc\"},\n            )\n            raise HTTPException(\n                status_code=HTTP_401_UNAUTHORIZED,\n                detail=\"Invalid token issuer\",\n            ) from None\n        except jwt.MissingRequiredClaimError as e:\n            logger.debug(\n                \"OIDC authentication failed\",\n                extra={\"reason\": \"missing_claim\", \"claim\": e.claim, \"scheme\": \"oidc\"},\n            )\n            raise HTTPException(\n                status_code=HTTP_401_UNAUTHORIZED,\n                detail=f\"Missing required claim: {e.claim}\",\n            ) from None\n        except jwt.PyJWKClientError as e:\n            logger.error(\n                \"OIDC authentication failed\",\n                extra={\n                    \"reason\": \"jwks_client_error\",\n                    \"error\": str(e),\n                    \"scheme\": \"oidc\",\n                },\n            )\n            raise HTTPException(\n                status_code=HTTP_503_SERVICE_UNAVAILABLE,\n                detail=\"Unable to fetch signing keys\",\n            ) from None\n        except jwt.InvalidTokenError as e:\n            logger.debug(","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai/src/crewai/a2a/auth/server_schemes.py#L315-L351","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Decode the token without verification and confirm which claim is absent; the detail message names it.","Ensure the client requests the token type/scopes that make the IdP include the missing claim (e.g. pass audience so `aud` is present).","If you generate tokens yourself for tests, include exp, iat, iss, and aud.","Do not relax validation by removing required claims unless you accept the security trade-off."],"exampleFix":"# before (test token missing standard claims)\nimport jwt\ntok = jwt.encode({\"sub\": \"user1\"}, key, algorithm=\"RS256\")  # 401 Missing required claim: exp\n\n# after\nimport time\ntok = jwt.encode(\n    {\"sub\": \"user1\", \"iss\": \"https://idp\", \"aud\": \"my-api\", \"iat\": int(time.time()), \"exp\": int(time.time()) + 3600},\n    key, algorithm=\"RS256\",\n)","handlingStrategy":"validation","validationCode":"import jwt\n\nREQUIRED = {\"exp\", \"iat\", \"iss\", \"aud\"}\nclaims = jwt.decode(access_token, options={\"verify_signature\": False})\nmissing = REQUIRED - claims.keys()\nassert not missing, f\"token missing required claims: {sorted(missing)}\"","typeGuard":null,"tryCatchPattern":"try:\n    await scheme.authenticate(token)\nexcept HTTPException as e:\n    if e.status_code == 401 and e.detail.startswith(\"Missing required claim:\"):\n        claim = e.detail.rsplit(\":\", 1)[1].strip()\n        # fix token issuance so `claim` is present, then retry","preventionTips":["Ensure the IdP issues all claims your validation requires (audience, expiry).","When minting test JWTs, include exp/iat/iss/aud.","Parse the claim name out of the 401 detail to pinpoint the gap."],"tags":["a2a","oidc","jwt","claims","http-401"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}