honojs/hono · error · HTTPException

no authorization included in request

Error message

no authorization included in request

What it means

The request carried no token at all (no Authorization header, or the header present but empty after parsing) and the middleware was not configured with allow_anon, so it rejects with a 401 HTTPException, error 'invalid_request', description 'no authorization included in request'.

Source

Thrown at src/middleware/jwk/jwk.ts:127

          )
        } else {
          token = await getSignedCookie(ctx, options.cookie.secret, options.cookie.key)
        }
      } else {
        if (options.cookie.prefixOptions) {
          token = getCookie(ctx, options.cookie.key, options.cookie.prefixOptions)
        } else {
          token = getCookie(ctx, options.cookie.key)
        }
      }
    }

    if (!token) {
      if (options.allow_anon) {
        return next()
      }
      const errDescription = 'no authorization included in request'
      throw new HTTPException(401, {
        message: errDescription,
        res: unauthorizedResponse({
          ctx,
          error: 'invalid_request',
          errDescription,
          realm: options.realm,
        }),
      })
    }

    let payload
    let cause
    try {
      const keys = typeof options.keys === 'function' ? await options.keys(ctx) : options.keys
      const jwks_uri =
        typeof options.jwks_uri === 'function' ? await options.jwks_uri(ctx) : options.jwks_uri
      payload = await Jwt.verifyWithJwks(
        token,

View on GitHub (pinned to e2740d5a1b)

Solutions

  1. Send the token: add 'Authorization: Bearer <jwt>' to the request
  2. If the route should allow unauthenticated access, set allow_anon: true in the jwk options and do your own identity check downstream
  3. Verify headerName matches what the client sends (default is Authorization)
  4. Narrow the middleware mount so only truly protected routes require tokens

Example fix

// before
app.use('/api/*', jwk({ jwks_uri }))
// after
app.use('/api/*', jwk({ jwks_uri, allow_anon: true }))
Defensive patterns

Strategy: validation

Validate before calling

const hasToken = (req: Request): boolean => {
  const h = req.headers.get('Authorization')
  return !!h && /^bearer\s+\S+$/i.test(h)
}

Type guard

const requestHasBearer = (req: Request): boolean => {
  const parts = (req.headers.get('Authorization') || '').split(/\s+/)
  return parts.length === 2 && parts[0].toLowerCase() === 'bearer' && !!parts[1]
}

Try / catch

try { await protectedCall() } catch (e) { if (e instanceof HTTPException && e.status === 401) { /* redirect to login: no token present */ } }

Prevention

When it happens

Trigger: Any request to a jwk-protected route without an Authorization header, with an empty header value, or where the configured headerName is absent (e.g. expecting X-Auth-Token but the client sends Authorization).

Common situations: Public/unauthenticated pages accidentally falling under a broad app.use('/api/*', jwk(...)) mount; browser navigations that never attach Authorization; headerName mismatch after refactors; health-check probes hitting protected endpoints.

Related errors


AI-assisted analysis of honojs/hono@e2740d5a1b (2026-08-28). Data as JSON: /api/errors/06faf1b310ad15c8. Report an issue: GitHub.