{"record":{"id":"e62b215d6b51e3f9","repo":"honojs/hono","slug":"jwk-auth-middleware-requires-options-for-either-k","errorCode":null,"errorMessage":"JWK auth middleware requires options for either \"keys\" or \"jwks_uri\" or both","messagePattern":"JWK auth middleware requires options for either \"keys\" or \"jwks_uri\" or both","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/middleware/jwk/jwk.ts","lineNumber":71,"sourceCode":"    allow_anon?: boolean\n    cookie?:\n      | string\n      | { key: string; secret?: string | BufferSource; prefixOptions?: CookiePrefixOptions }\n\n    headerName?: string\n\n    alg: AsymmetricAlgorithm[]\n\n    realm?: string\n\n    verification?: VerifyOptions\n  },\n  init?: RequestInit\n): MiddlewareHandler => {\n  const verifyOpts = options.verification || {}\n\n  if (!options || !(options.keys || options.jwks_uri)) {\n    throw new Error('JWK auth middleware requires options for either \"keys\" or \"jwks_uri\" or both')\n  }\n\n  if (!crypto.subtle || !crypto.subtle.importKey) {\n    throw new Error('`crypto.subtle.importKey` is undefined. JWK auth middleware requires it.')\n  }\n\n  return async function jwk(ctx, next) {\n    const headerName = options.headerName || 'Authorization'\n\n    const credentials = ctx.req.raw.headers.get(headerName)\n    let token\n    if (credentials) {\n      const parts = credentials.split(/\\s+/)\n      if (parts.length !== 2 || parts[0].toLowerCase() !== 'bearer') {\n        const errDescription = 'invalid credentials structure'\n        throw new HTTPException(401, {\n          message: errDescription,\n          res: unauthorizedResponse({","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/honojs/hono/blob/e2740d5a1bd0b4254e517e3af8b60789284bc7bd/src/middleware/jwk/jwk.ts#L53-L89","documentation":"The JWK auth middleware requires at least one source of verification keys: either static 'keys' (an array of JWKs / a JWKS), a 'jwks_uri' to fetch keys from, or both. If neither is present in the options object, construction fails immediately with this error.","triggerScenarios":"Calling jwk() with an empty options object, only a 'realm'/'headerName' setting, or only cookie options — i.e., omitting both options.keys and options.jwks_uri.","commonSituations":"Loading keys conditionally from env and accidentally passing undefined (e.g. keys: process.env.JWKS ? JSON.parse(...) : undefined) when the env var is missing; typos like 'key' or 'jwksUrl'; refactors that moved key config into a nested 'verification' object, which does not count as the key source.","solutions":["Pass options.keys (JWKS/JWK array) or options.jwks_uri (e.g. your IdP's https://.../jwks.json endpoint)","If keys come from env/config, validate at startup that at least one source resolves to a truthy value before creating the middleware","Check spelling: the field is jwks_uri (snake_case), not jwksUri or jwksUrl","If you fetch keys dynamically, point jwks_uri at the issuer's JWKS endpoint rather than passing a fetched array conditionally"],"exampleFix":"// before\napp.use('/api/*', jwk({ realm: 'api' }))\n// after\napp.use('/api/*', jwk({ jwks_uri: 'https://issuer.example.com/.well-known/jwks.json', realm: 'api' }))","handlingStrategy":"type-guard","validationCode":"const hasKeySource = (o: { keys?: unknown; jwks_uri?: string } | undefined): boolean =>\n  !!o && (!!o.keys || !!o.jwks_uri)\nif (!hasKeySource(opts)) throw new Error('JWK config incomplete')","typeGuard":"interface JwkOpts { keys?: unknown[]; jwks_uri?: string }\nconst hasJwkKeySource = (o: JwkOpts | undefined): o is Required<Pick<JwkOpts,'keys'|'jwks_uri'>> & JwkOpts =>\n  !!o && (!!o.keys || !!o.jwks_uri)","tryCatchPattern":"try { app.use(jwk(opts)) } catch (e) { if (e instanceof Error && /keys.*jwks_uri/.test(e.message)) { /* fail startup with clear config error */ } throw e }","preventionTips":["Fail fast at boot: assert keys or jwks_uri is present before creating the middleware","Type the options object so keys/jwks_uri are explicit, not conditionally undefined","Double-check the exact field name jwks_uri (snake_case)","Put a startup smoke test that constructs the middleware in CI"],"tags":["jwk","jwt","auth","configuration","middleware"],"backgroundTag":"missing-auth-configuration","analyzedSha":"e2740d5a1bd0b4254e517e3af8b60789284bc7bd","analyzedAt":"2026-08-28T10:18:08.750Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}