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
The client did not send an Authorization header
commonThe request reached the route without a token — the user was not logged in, the client forgot to attach the header, or the token expired client-side and was cleared. Code like `req.headers.authorization.split(" ")[1]` then yields `undefined`.
The token is read from the wrong place
commonMisspelled properties (`authorisation`, `Authorization` on a lower-cased header map), a custom header such as `x-access-token`, or a query parameter the code does not read. Node lower-cases incoming header names, so `req.headers.Authorization` is always `undefined`.
The session cookie did not travel
occasionalCross-origin requests omit cookies unless the client sets `credentials: "include"` and the cookie is `SameSite=None; Secure`. Without cookie-parser middleware, `req.cookies` is empty as well.
The token was not ready yet
occasionalFront ends that fetch data before the login flow stores the token, or that read the token from storage asynchronously, send the first requests with an empty value.
How to fix it
- 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.
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" });