Skip to content
ecdsa.com
express-jwt (Node.js)JWT libraries

Error message

UnauthorizedError: No authorization token was found

Also printed as

  • No authorization token was found
  • Format is Authorization: Bearer [token]

Unhandled, Express prints the error with its stack, starting with "UnauthorizedError: No authorization token was found". `err.code` distinguishes `credentials_required` (no token) from `credentials_bad_scheme` and `credentials_bad_format` ("Format is Authorization: Bearer [token]").

express-jwt (Node.js) — UnauthorizedError, code credentials_required

What it means

express-jwt protects the route but found no token: the request has no `Authorization` header and no custom `getToken` function returned one. Because `credentialsRequired` defaults to `true`, the middleware raises `UnauthorizedError` with `code: "credentials_required"` and `status: 401`, and the request never reaches your handler. A header that is present but not of the form `Bearer <token>` fails with "Format is Authorization: Bearer [token]" instead.

Why it happens

How to fix it

  1. 1.

    Tell express-jwt where the token is

    `getToken` receives the request and returns the token string or `null`. Keep it simple and avoid accepting tokens from several places at once.

    js
    import cookieParser from "cookie-parser";
    import { expressjwt } from "express-jwt";
    
    app.use(cookieParser());
    app.use(
      expressjwt({
        secret: getSigningKey,          // e.g. jwks-rsa's expressJwtSecret(...)
        algorithms: ["RS256"],
        getToken: (req) => req.cookies.access_token ?? null,
      }),
    );
  2. 2.

    Exempt public routes, or make authentication optional

    `.unless()` skips listed paths. `credentialsRequired: false` lets requests without a token through with no `req.auth`, so each route can decide.

    js
    app.use(
      expressjwt({ secret, algorithms: ["HS256"] }).unless({ path: ["/health", "/login", /^\/public\//] }),
    );
    
    // Or keep authentication optional and decide per route:
    app.use(expressjwt({ secret, algorithms: ["HS256"], credentialsRequired: false }));
  3. 3.

    Turn the error into a proper 401

    Express's default handler uses the error's `status` (401) but answers with an HTML page — including the stack trace in development — and no `WWW-Authenticate` header. Map `UnauthorizedError` to a JSON 401 with that header yourself.

    js
    app.use((err, req, res, next) => {
      if (err.name === "UnauthorizedError") {
        return res.status(401).set("WWW-Authenticate", "Bearer").json({ error: err.code });
      }
      next(err);
    });

Related errors

Browse the full signature error database