expressjs/express · error · Error

cookieParser("secret") required for signed cookies

Error message

cookieParser("secret") required for signed cookies

What it means

Thrown by `res.cookie` when `options.signed` is true but `req.secret` is undefined. Signed cookies are HMAC-signed with a secret that the cookie-parser middleware places on `req.secret`; without it Express cannot compute the signature, so it fails fast rather than emitting an unsigned cookie that claims to be signed.

Source

Thrown at lib/response.js:751

 *    res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
 *
 *    // same as above
 *    res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
 *
 * @param {String} name
 * @param {String|Object} value
 * @param {Object} [options]
 * @return {ServerResponse} for chaining
 * @public
 */

res.cookie = function (name, value, options) {
  var opts = { ...options };
  var secret = this.req.secret;
  var signed = opts.signed;

  if (signed && !secret) {
    throw new Error('cookieParser("secret") required for signed cookies');
  }

  var val = typeof value === 'object'
    ? 'j:' + JSON.stringify(value)
    : String(value);

  if (signed) {
    val = 's:' + sign(val, secret);
  }

  if (opts.maxAge != null) {
    var maxAge = opts.maxAge - 0

    if (!isNaN(maxAge)) {
      opts.expires = new Date(Date.now() + maxAge)
      opts.maxAge = Math.floor(maxAge / 1000)
    }
  }

View on GitHub ↗ (pinned to a3714473fe)

Solutions

  1. Register cookie-parser with a secret before your routes: `app.use(cookieParser(process.env.COOKIE_SECRET))` — and verify the env var is actually set.
  2. Check middleware order: cookieParser must be app.use'd before any route that sets signed cookies.
  3. If you don't need tamper-proof cookies, drop `signed: true` from the options.
  4. Alternatively set `req.secret` yourself in earlier middleware if you're not using cookie-parser.

Example fix

// before
app.use(cookieParser());
res.cookie('session', id, { signed: true }); // throws
// after
app.use(cookieParser(process.env.COOKIE_SECRET));
res.cookie('session', id, { signed: true });
Defensive patterns

Strategy: validation

Validate before calling

const cookieParser = require('cookie-parser');
app.use(cookieParser(process.env.COOKIE_SECRET)); // must be BEFORE any res.cookie(..., { signed: true })
if (!process.env.COOKIE_SECRET) throw new Error('COOKIE_SECRET env var not set');

Prevention

When it happens

Trigger: `res.cookie('name', value, { signed: true })` when the app never registered `cookieParser('some-secret')`, registered it with no argument, or registered it after the route / on a different router so req.secret isn't set for this request.

Common situations: Adding `signed: true` without updating middleware setup; cookie-parser mounted without a secret (`app.use(cookieParser())`); middleware ordering bugs where the route runs before cookie-parser; secret sourced from an env var that is unset in the deployment environment.

Related errors


AI-assisted analysis of expressjs/express@a3714473fe (2026-07-31). Data as JSON: /data/errors/d1bdf730c549b674.json. Report an issue: GitHub ↗.