Skip to content
ecdsa.com
jsonwebtoken (Node.js)JWT libraries

Error message

jwt must be provided

jsonwebtoken (Node.js) — JsonWebTokenError from jwt.verify()

What it means

`jwt.verify()` received no token at all: the first argument was `undefined`, `null` or an empty string. jsonwebtoken checks this before parsing, so neither the key nor the token format matters yet. The problem is upstream — the code that extracts the token from the request found nothing.

Why it happens

How to fix it

  1. 1.

    Extract the token defensively and answer 401

    Check for a missing token before calling `verify` and return 401 with a `WWW-Authenticate: Bearer` header. Clients then see "not authenticated" instead of a 500 from an uncaught error.

    js
    function bearerToken(req) {
      const [scheme, token] = (req.headers.authorization ?? "").split(" ");
      return scheme?.toLowerCase() === "bearer" && token ? token : null;
    }
    
    app.use((req, res, next) => {
      const token = bearerToken(req);
      if (!token) return res.status(401).set("WWW-Authenticate", "Bearer").end();
      try {
        req.user = jwt.verify(token, publicKey, { algorithms: ["ES256"] });
        next();
      } catch {
        res.status(401).set("WWW-Authenticate", 'Bearer error="invalid_token"').end();
      }
    });
  2. 2.

    Make the client attach the token

    Confirm in the browser's network panel that the request carries `Authorization: Bearer …` (or the cookie). If the header is visible in the browser but missing on the server, a proxy in between strips it.

    js
    // Browser / Node 18+ fetch: the token must be attached explicitly.
    await fetch("https://api.example.com/orders", {
      headers: { Authorization: "Bearer " + accessToken },
    });
    
    // Cookies cross origins only with credentials and SameSite=None; Secure.
    await fetch("https://api.example.com/orders", { credentials: "include" });

Related errors

Browse the full signature error database