{"record":{"id":"83e19e74b6876000","repo":"honojs/hono","slug":"required-aud-in-jwt-payload-json-stringify-pa","errorCode":null,"errorMessage":"required \"aud\" in jwt payload: ${JSON.stringify(payload)}","messagePattern":"required \"aud\" in jwt payload: (.+?)","errorType":"exception","errorClass":"JwtPayloadRequiresAud","httpStatus":null,"severity":"error","filePath":"src/utils/jwt/jwt.ts","lineNumber":160,"sourceCode":"    if (typeof payload.iat !== 'number' || !Number.isFinite(payload.iat) || now < payload.iat) {\n      throw new JwtTokenIssuedAt(now, payload.iat)\n    }\n  }\n  if (iss) {\n    if (!payload.iss) {\n      throw new JwtTokenIssuer(iss, null)\n    }\n    if (typeof iss === 'string' && payload.iss !== iss) {\n      throw new JwtTokenIssuer(iss, payload.iss)\n    }\n    if (iss instanceof RegExp && !iss.test(payload.iss)) {\n      throw new JwtTokenIssuer(iss, payload.iss)\n    }\n  }\n\n  if (aud) {\n    if (!payload.aud) {\n      throw new JwtPayloadRequiresAud(payload)\n    }\n\n    const audiences = Array.isArray(payload.aud) ? payload.aud : [payload.aud]\n    const matched = audiences.some((payloadAud): boolean =>\n      aud instanceof RegExp\n        ? aud.test(payloadAud)\n        : typeof aud === 'string'\n          ? payloadAud === aud\n          : Array.isArray(aud) && aud.includes(payloadAud)\n    )\n    if (!matched) {\n      throw new JwtTokenAudience(aud, payload.aud)\n    }\n  }\n\n  const headerPayload = token.substring(0, token.lastIndexOf('.'))\n  const verified = await verifying(\n    publicKey,","sourceCodeStart":142,"sourceCodeEnd":178,"githubUrl":"https://github.com/honojs/hono/blob/e2740d5a1bd0b4254e517e3af8b60789284bc7bd/src/utils/jwt/jwt.ts#L142-L178","documentation":"Thrown when audience (aud) validation is requested via the aud option but the token payload contains no aud claim. The library requires the claim to be present before it can attempt matching.","triggerScenarios":"verify(token, key, { aud: 'my-api' }) or verifyWithJwks with verification.aud set, and the decoded payload has no aud field (JwtPayloadRequiresAud).","commonSituations":"ID tokens (which target a client_id, sometimes absent) verified as access tokens; audience not configured in the IdP for your API; custom tokens minted without aud; passing aud option when the token type never carries it.","solutions":["Decode the token and confirm whether aud exists and what value it holds","Configure your API as an audience/scope in your IdP so tokens include aud","Set the aud option to the value your IdP actually emits","Remove the aud option if audience validation is unnecessary for this token type"],"exampleFix":"// before\nawait verify(token, key, { aud: 'https://api.example.com' }) // token has no aud\n// after\nawait verify(token, key, {}) // or configure IdP to emit aud: 'https://api.example.com'","handlingStrategy":"validation","validationCode":"const payload = decodePayload(token)\nif (!('aud' in payload)) throw new BadRequest('token missing aud')","typeGuard":"const hasAud = (p: unknown): p is { aud: string | string[] } =>\n  typeof p === 'object' && p !== null && 'aud' in p","tryCatchPattern":null,"preventionTips":["Verify access tokens (which carry aud) rather than ID tokens for API auth","Configure audience in IdP"],"tags":["jwt","audience-validation","authentication"],"backgroundTag":"jwt-audience-mismatch","analyzedSha":"e2740d5a1bd0b4254e517e3af8b60789284bc7bd","analyzedAt":"2026-08-28T10:18:08.750Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}