{"id":"d1bdf730c549b674","repo":"expressjs/express","slug":"cookieparser-secret-required-for-signed-cookies","errorCode":null,"errorMessage":"cookieParser(\"secret\") required for signed cookies","messagePattern":"cookieParser\\(\"secret\"\\) required for signed cookies","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/response.js","lineNumber":751,"sourceCode":" *    res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });\n *\n *    // same as above\n *    res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })\n *\n * @param {String} name\n * @param {String|Object} value\n * @param {Object} [options]\n * @return {ServerResponse} for chaining\n * @public\n */\n\nres.cookie = function (name, value, options) {\n  var opts = { ...options };\n  var secret = this.req.secret;\n  var signed = opts.signed;\n\n  if (signed && !secret) {\n    throw new Error('cookieParser(\"secret\") required for signed cookies');\n  }\n\n  var val = typeof value === 'object'\n    ? 'j:' + JSON.stringify(value)\n    : String(value);\n\n  if (signed) {\n    val = 's:' + sign(val, secret);\n  }\n\n  if (opts.maxAge != null) {\n    var maxAge = opts.maxAge - 0\n\n    if (!isNaN(maxAge)) {\n      opts.expires = new Date(Date.now() + maxAge)\n      opts.maxAge = Math.floor(maxAge / 1000)\n    }\n  }","sourceCodeStart":733,"sourceCodeEnd":769,"githubUrl":"https://github.com/expressjs/express/blob/a3714473feb3d2908add734d340e7755fd85e0a3/lib/response.js#L733-L769","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","solutions":["Register cookie-parser with a secret before your routes: `app.use(cookieParser(process.env.COOKIE_SECRET))` — and verify the env var is actually set.","Check middleware order: cookieParser must be app.use'd before any route that sets signed cookies.","If you don't need tamper-proof cookies, drop `signed: true` from the options.","Alternatively set `req.secret` yourself in earlier middleware if you're not using cookie-parser."],"exampleFix":"// before\napp.use(cookieParser());\nres.cookie('session', id, { signed: true }); // throws\n// after\napp.use(cookieParser(process.env.COOKIE_SECRET));\nres.cookie('session', id, { signed: true });","handlingStrategy":"validation","validationCode":"const cookieParser = require('cookie-parser');\napp.use(cookieParser(process.env.COOKIE_SECRET)); // must be BEFORE any res.cookie(..., { signed: true })\nif (!process.env.COOKIE_SECRET) throw new Error('COOKIE_SECRET env var not set');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register cookieParser(secret) as app-level middleware before any route that sets signed cookies","Fail fast at startup if the cookie secret env var is missing rather than discovering it at request time","Keep the secret in an environment variable, never hardcoded; verify presence by name at boot"],"tags":["express","cookies","cookie-parser","configuration","security"],"analyzedSha":"a3714473feb3d2908add734d340e7755fd85e0a3","analyzedAt":"2026-07-31T18:55:36.968Z","schemaVersion":2}