{"record":{"id":"9066baba458c38d6","repo":"honojs/hono","slug":"unauthorized-9066ba","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":"HTTPException","httpStatus":401,"severity":"error","filePath":"src/middleware/jwk/jwk.ts","lineNumber":157,"sourceCode":"    let cause\n    try {\n      const keys = typeof options.keys === 'function' ? await options.keys(ctx) : options.keys\n      const jwks_uri =\n        typeof options.jwks_uri === 'function' ? await options.jwks_uri(ctx) : options.jwks_uri\n      payload = await Jwt.verifyWithJwks(\n        token,\n        { keys, jwks_uri, verification: verifyOpts, allowedAlgorithms: options.alg },\n        init\n      )\n    } catch (e) {\n      cause = e\n    }\n\n    if (!payload) {\n      if (cause instanceof Error && cause.constructor === Error) {\n        throw cause\n      }\n      throw new HTTPException(401, {\n        message: 'Unauthorized',\n        res: unauthorizedResponse({\n          ctx,\n          error: 'invalid_token',\n          statusText: 'Unauthorized',\n          errDescription: 'token verification failure',\n          realm: options.realm,\n        }),\n        cause,\n      })\n    }\n\n    ctx.set('jwtPayload', payload)\n\n    await next()\n  }\n}\n","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/honojs/hono/blob/e2740d5a1bd0b4254e517e3af8b60789284bc7bd/src/middleware/jwk/jwk.ts#L139-L175","documentation":"A token was supplied but verification (signature check against the JWKs, and related JWKS fetch/parse steps) failed, so the middleware throws a 401 HTTPException with error 'invalid_token'. A bare underlying Error (not a subclass) is rethrown as-is; otherwise the HTTPException includes 'token verification failure' in the response body.","triggerScenarios":"Token signed with a different key than those in keys/jwks_uri (kid mismatch or rotated keys), a tampered or truncated JWT, an expired/malformed token surfaced as verification failure, or a failure fetching/parsing the JWKS endpoint (network error, invalid JSON).","commonSituations":"Key rotation on the IdP while the app cached old keys; wrong jwks_uri or environment mismatch (prod token against staging keys); clock skew causing validation errors; proxies stripping Authorization content; JWKS endpoint returning HTML error pages.","solutions":["Confirm the token's issuer/kid matches a key in the configured JWKS; log the kid header and compare against the fetched key set","If keys rotated, ensure jwks_uri is used (dynamic fetch) rather than stale static keys","Verify network access to jwks_uri from the runtime (curl it from the same container) and that it returns valid JSON","Check that the token itself is intact (not truncated or re-encoded) and, for Node runtimes, that fetch is available for JWKS retrieval"],"exampleFix":"// before\napp.use(jwk({ keys: oldKeys })) // stale after IdP rotation\n// after\napp.use(jwk({ jwks_uri: 'https://issuer.example.com/.well-known/jwks.json' }))","handlingStrategy":"try-catch","validationCode":"import { jwtVerify, createRemoteJWKSet } from 'jose' // optional pre-check\nconst precheck = async (token: string, jwks: any) => {\n  try { await jwtVerify(token, jwks); return true } catch { return false }\n}","typeGuard":null,"tryCatchPattern":"try { return await handler(ctx, next) } catch (e) {\n  if (e instanceof HTTPException && e.status === 401) {\n    const body = await e.res?.clone().json().catch(() => null)\n    if (body?.error === 'invalid_token') { /* key mismatch/rotation: log kid, refresh JWKS */ }\n  }\n  throw e\n}","preventionTips":["Prefer jwks_uri over static keys so rotation is picked up automatically","Log the token's kid header on 401s and compare against your JWKS","Verify jwks_uri is reachable and returns JSON from the deployment environment","Sync clocks (NTP) on servers validating exp/iat claims"],"tags":["jwk","jwt","http-401","signature-verification","auth"],"backgroundTag":"jwt-signature-verification-failed","analyzedSha":"e2740d5a1bd0b4254e517e3af8b60789284bc7bd","analyzedAt":"2026-08-28T10:18:08.750Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}