hasura/graphql-engine · error · Error

Required claim {claim_name} not found

Error message

Required claim {claim_name} not found

What it means

A claim declared as required (via the claims map or required-claims configuration) is absent from the verified JWT payload.

Source

Thrown at v3/crates/auth/hasura-authn-jwt/src/jwt.rs:46

pub enum Error {
    #[error("Error decoding the `Authorization` header - {0}")]
    ErrorDecodingAuthorizationHeader(jwt::errors::Error),
    #[error("`kid` (Key ID) header claim not found in the header")]
    KidHeaderNotFound,
    #[error("Expected the Hasura claims to be a String when `claimsFormat` is `stringifiedJson`")]
    ExpectedStringifiedJson,
    #[error("The default role is not present in the allowed roles")]
    DisallowedDefaultRole,
    #[error("The specified role is not present in the allowed roles")]
    DisallowedRole,
    #[error("Error while parsing the claims map entry: {claim_name} - {err}")]
    ParseClaimsMapEntryError {
        claim_name: String,
        err: serde_json::Error,
    },
    #[error("Expected string value for claim {claim_name}")]
    ClaimMustBeAString { claim_name: String },
    #[error("Required claim {claim_name} not found")]
    RequiredClaimNotFound { claim_name: String },
    #[error("JWT Authorization token source: Header name {header_name} not found.")]
    AuthorizationHeaderSourceNotFound { header_name: String },
    #[error("JWT Authorization token source: Cookie header not found")]
    CookieNotFound,
    #[error(
        "JWT Authorization token source: cookie name {cookie_name} not found in the Cookie header"
    )]
    CookieNameNotFound { cookie_name: String },
    #[error("Error in parsing the {header_name} header: {err}")]
    AuthorizationHeaderParseError { err: String, header_name: String },
    #[error("Error in parsing the Cookie header value: {err}")]
    CookieParseError { err: cookie::ParseError },
    #[error("Missing corresponding value for the cookie with cookie name: {cookie_name}")]
    MissingCookieValue { cookie_name: String },
    #[error("JWT validation error: {0}")]
    JWTValidationError(jwt::errors::Error),
    #[error("Internal Error - {0}")]

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Decode the JWT and confirm whether {claim_name} is present
  2. Fix the claims map / namespace configuration to match the token's actual claim names
  3. Update the auth server to include the required claim in issued tokens
  4. Check you are using the correct token (not a refresh token or a token from another app)

Example fix

// before: claims_map expects "hasura-claims"
// after: claims_map expects "https://hasura.io/jwt/claims" (matching the issued token)
Defensive patterns

Strategy: validation

Validate before calling

const payload = decodeJwt(token);
const missing = requiredClaims.filter(c => !(c in payload));
if (missing.length) return reject('missing claims: ' + missing.join(','));

Type guard

const hasClaim = (p: object, c: string): c is keyof typeof p => c in p;

Try / catch

Catch and return 401 with the missing claim name; instruct the user to log in again.

Prevention

When it happens

Trigger: JWT validation succeeds cryptographically but the token payload lacks a claim listed in the claims map, e.g. missing `https://hasura.io/jwt/claims` namespace or missing default-role claim.

Common situations: Misconfigured JWT namespace in metadata vs. what the IdP emits; custom auth server forgets to include Hasura claims; using a token intended for a different audience/application.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/c512623af8b935cf. Report an issue: GitHub.