{"record":{"id":"ef31b5927bde42ca","repo":"honojs/hono","slug":"invalid-credentials-structure-ef31b5","errorCode":null,"errorMessage":"invalid credentials structure","messagePattern":"invalid credentials structure","errorType":"http","errorClass":"HTTPException","httpStatus":401,"severity":"error","filePath":"src/middleware/jwt/jwt.ts","lineNumber":87,"sourceCode":"\n  if (!options.alg) {\n    throw new Error('JWT auth middleware requires options for \"alg\"')\n  }\n\n  if (!crypto.subtle || !crypto.subtle.importKey) {\n    throw new Error('`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.')\n  }\n\n  return async function jwt(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({\n            ctx,\n            error: 'invalid_request',\n            errDescription,\n            realm: options.realm,\n          }),\n        })\n      } else {\n        token = parts[1]\n      }\n    } else if (options.cookie) {\n      if (typeof options.cookie == 'string') {\n        token = getCookie(ctx, options.cookie)\n      } else if (options.cookie.secret) {\n        if (options.cookie.prefixOptions) {\n          token = await getSignedCookie(\n            ctx,","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/honojs/hono/blob/e2740d5a1bd0b4254e517e3af8b60789284bc7bd/src/middleware/jwt/jwt.ts#L69-L105","documentation":"Identical to the JWK variant: the JWT middleware found an Authorization header but it did not consist of exactly 'Bearer <token>' (two whitespace-separated parts with a case-insensitive 'bearer' scheme). It throws a 401 HTTPException with error 'invalid_request' and this description.","triggerScenarios":"Requests with 'Authorization: Bearer' (missing token), 'Bearer abc.def' plus extra segments, schemes other than Bearer ('Basic ...', 'JWT ...'), or a custom headerName whose value lacks the Bearer prefix.","commonSituations":"API clients sending raw tokens without the Bearer prefix; custom API-key headers reused for JWT auth; malformed tokens containing spaces (copy-paste truncation); serverless platforms or gateways rewriting the Authorization header.","solutions":["Send exactly 'Authorization: Bearer <token>' (single space, two parts, no trailing whitespace)","If using headerName other than Authorization, still include the 'Bearer ' prefix in that header's value","Check for gateways/proxies that append or normalize the Authorization header","Add a client-side guard matching /^Bearer \\S+$/ before issuing the request"],"exampleFix":"// before\nheaders: { Authorization: `${token}` }\n// after\nheaders: { Authorization: `Bearer ${token}` }","handlingStrategy":"validation","validationCode":"const isBearer = (h: string | null): boolean => !!h && h.split(/\\s+/).length === 2 && h.split(/\\s+/)[0].toLowerCase() === 'bearer'","typeGuard":"const isBearerCredentials = (credentials: string | null | undefined): credentials is string =>\n  !!credentials && /^bearer\\s+\\S+$/i.test(credentials)","tryCatchPattern":"try { await fetch('/api/data', { headers: { Authorization: `Bearer ${token}` } }) } catch (e) { if (e instanceof HTTPException && e.status === 401) { /* check res body: 'invalid credentials structure' means header format, not token validity */ } }","preventionTips":["Always send `Authorization: Bearer ${token}` exactly","Avoid schemes like Basic or API-key values on JWT endpoints","Check that proxies/gateways do not rewrite the Authorization header","Validate the header client-side with /^Bearer \\S+$/ before sending"],"tags":["jwt","authorization-header","http-401","auth"],"backgroundTag":"malformed-authorization-header","analyzedSha":"e2740d5a1bd0b4254e517e3af8b60789284bc7bd","analyzedAt":"2026-08-28T10:18:08.750Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}