Error message
secret or public key must be provided
Also printed as
- secretOrPrivateKey must have a value
`jwt.sign()` reports the same problem as "secretOrPrivateKey must have a value" (a plain `Error`).
jsonwebtoken (Node.js) — JsonWebTokenError from jwt.verify(); the sign() twin is a plain Error
What it means
`jwt.verify()` received a signed token but the key argument is empty (`undefined`, `null` or `""`). jsonwebtoken cannot check a signature without a key, so it stops before looking at the token. The signing side has a twin, `secretOrPrivateKey must have a value`, thrown by `jwt.sign()` for the same reason.
Why it happens
The environment variable is not set here
common`process.env.JWT_SECRET` or `JWT_PUBLIC_KEY` exists on a developer machine but not in the container, the CI job or the serverless function. Platform dashboards often scope variables per environment (preview vs production).
.env is loaded after the value was read
commonA module that reads `process.env.JWT_SECRET` at import time captures `undefined` when `dotenv` is configured later in the entry file. With ES modules, imports are evaluated before the code of the importing file runs.
A key callback resolved to nothing
occasionalWith a `getKey(header, callback)` function (for example backed by jwks-rsa), calling `callback(null, undefined)` — because a lookup returned no key — produces this error instead of a key-not-found error.
How to fix it
- 1.
Validate configuration at startup
Read required keys once when the process starts and exit with a clear message if one is missing. A misconfigured instance then never starts serving requests.
js function requireEnv(name) { const value = process.env[name]; if (!value) throw new Error(name + " is not set"); return value; } const JWT_PUBLIC_KEY = requireEnv("JWT_PUBLIC_KEY"); // evaluated once at startup - 2.
Load environment files before anything else
Import `dotenv/config` as the very first import, or use Node's built-in `--env-file` flag, so every module sees the values.
js // Load .env before any module that reads process.env at import time. import "dotenv/config"; import { app } from "./app.js"; // Node 20.6+: no package needed // node --env-file=.env server.js