honojs/hono · error · HTTPException
invalid credentials structure
Error message
invalid credentials structure
What it means
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.
Source
Thrown at src/middleware/jwt/jwt.ts:87
if (!options.alg) {
throw new Error('JWT auth middleware requires options for "alg"')
}
if (!crypto.subtle || !crypto.subtle.importKey) {
throw new Error('`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.')
}
return async function jwt(ctx, next) {
const headerName = options.headerName || 'Authorization'
const credentials = ctx.req.raw.headers.get(headerName)
let token
if (credentials) {
const parts = credentials.split(/\s+/)
if (parts.length !== 2 || parts[0].toLowerCase() !== 'bearer') {
const errDescription = 'invalid credentials structure'
throw new HTTPException(401, {
message: errDescription,
res: unauthorizedResponse({
ctx,
error: 'invalid_request',
errDescription,
realm: options.realm,
}),
})
} else {
token = parts[1]
}
} else if (options.cookie) {
if (typeof options.cookie == 'string') {
token = getCookie(ctx, options.cookie)
} else if (options.cookie.secret) {
if (options.cookie.prefixOptions) {
token = await getSignedCookie(
ctx,View on GitHub (pinned to e2740d5a1b)
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
Example fix
// before
headers: { Authorization: `${token}` }
// after
headers: { Authorization: `Bearer ${token}` } Defensive patterns
Strategy: validation
Validate before calling
const isBearer = (h: string | null): boolean => !!h && h.split(/\s+/).length === 2 && h.split(/\s+/)[0].toLowerCase() === 'bearer'
Type guard
const isBearerCredentials = (credentials: string | null | undefined): credentials is string => !!credentials && /^bearer\s+\S+$/i.test(credentials)
Try / catch
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 */ } } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- invalid credentials structure
- no authorization included in request
- Unauthorized
- JWK auth middleware requires options for either "keys" or "j
- required "aud" in jwt payload: ${JSON.stringify(payload)}
AI-assisted analysis of honojs/hono@e2740d5a1b (2026-08-28).
Data as JSON: /api/errors/ef31b5927bde42ca.
Report an issue: GitHub.