Skip to content

hook: false unexpectedly disables cookie writing, contradicting the docs ("disable autoparsing") #359

Description

@0XFF-96

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Fastify version

5.10.0

Plugin version

11.0.2

Node.js version

22.22.2

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

26.5.2

Description

Prerequisites

Fastify / plugin / Node versions

  • @fastify/cookie: 11.0.2
  • fastify: 5.10.0
  • node: 22.22.2

Description

When the plugin is registered with hook: false, reply.setCookie() (and
clearCookie()) become silent no-ops — the call succeeds and returns
reply, but no Set-Cookie header is ever written to the response.

The docs describe hook as controlling cookie parsing only:

hook: 'onRequest' // set to false to disable cookie autoparsing
hook: the Fastify Hook to register the parsing of cookie into.

So hook: false is documented to disable inbound parsing. Disabling the
outbound write path as well is undocumented and surprising, especially since
setCookie is still decorated onto reply and gives no error.

Steps to Reproduce

const Fastify = require('fastify')
const fastifyCookie = require('@fastify/cookie')

async function run (hookOption) {
  const app = Fastify()
  await app.register(fastifyCookie, { hook: hookOption })
  app.get('/', (req, reply) => {
    reply.setCookie('foo', 'bar', { path: '/' }).send({ ok: true })
  })
  const res = await app.inject({ method: 'GET', url: '/' })
  await app.close()
  return res.headers['set-cookie']
}

;(async () => {
  for (const opt of ['onRequest', false]) {
    console.log(`hook=${String(opt).padEnd(9)} ->`, await run(opt) ?? 'MISSING')
  }
})()

Output:

hook=onRequest -> foo=bar; Path=/; SameSite=Lax
hook=false     -> MISSING

Expected Behavior

hook: false should disable only autoparsing (as documented). reply.setCookie()
should still write the Set-Cookie header.

Root Cause

In index.js, the onSend handler that flushes queued cookies to the
Set-Cookie header is registered inside the same if (hook) block that gates
the parsing hook:

if (hook) {
  fastify.addHook(hook, onReqHandlerWrapper(fastify, hook))
  fastify.addHook('onSend', fastifyCookieOnSendHandler) // gated by parsing option
}

With hook: false, fastifyCookieOnSendHandler is never registered, so cookies
queued by setCookie into reply[kReplySetCookies] are never serialized out.

Fix

Register the onSend writer unconditionally; only the parsing hook should be
gated by hook:

if (hook) {
  fastify.addHook(hook, onReqHandlerWrapper(fastify, hook))
}
fastify.addHook('onSend', fastifyCookieOnSendHandler)

fastifyCookieOnSendHandler already early-returns when reply[kReplySetCookies]
is unset, so this adds no behavior when setCookie is not used. Happy to open a
PR with this fix plus a regression test.

Link to code that reproduces the bug

https://github.com/0XFF-96/fastify-cookie/tree/repro/hook-false-setcookie

Expected Behavior

hook: false should disable only cookie autoparsing (per the docs), not cookie
writing — reply.setCookie() should still set the Set-Cookie header. Currently
it is a silent no-op and no header is written.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed bug

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions