Skip to content

Multiple setCookie calls only set the last cookie #1075

@GoncaloJoseMoura

Description

@GoncaloJoseMoura

Environment

Nuxt Version: 4.1.3 (also tested with 3.14.159)
Nitro Version: 2.12.6
h3 Version: 1.15.4
Node Version: 20.x.x
Operating System: macOS
Package Manager: pnpm

Reproduction

Steps to reproduce

Create a fresh Nuxt project:

pnpm create nuxt@latest
cd nuxt-app
pnpm install

Create server/api/test.ts:

export default defineEventHandler(async (event) => {
  setCookie(event, "foo", "bar")
  setCookie(event, "monkey", "trial")
  setCookie(event, "good", "morning")
  
  console.log('Response headers:', event.node.res.getHeaders())
  
  return { ok: true }
})

Start the dev server:

pnpm dev

Test the endpoint:

curl -i http://localhost:3000/api/test

Describe the bug

Expected Behavior

The HTTP response should contain all three Set-Cookie headers:
HTTP/1.1 200 OK
Set-Cookie: foo=bar; Path=/
Set-Cookie: monkey=trial; Path=/
Set-Cookie: good=morning; Path=/

Actual Behavior

Only the last cookie is set:
HTTP/1.1 200 OK
set-cookie: good=morning; Path=/
However, the server console log shows all three cookies:

Response headers: {
  vary: 'Accept-Encoding',
  'set-cookie': [
    'foo=bar; Path=/',
    'monkey=trial; Path=/',
    'good=morning; Path=/'
  ]
}

Additional Testing

Raw Node.js server works correctly
Created a test with raw Node.js HTTP server (no Nuxt/Nitro):

const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, {
    'Content-Type': 'application/json',
    'Set-Cookie': [
      'foo=bar; Path=/',
      'monkey=trial; Path=/',
      'good=morning; Path=/'
    ]
  });
  res.end(JSON.stringify({ ok: true }));
});

server.listen(3001);

Testing with curl -i http://localhost:3001 correctly shows all 3 cookies, confirming Node.js itself works fine.

Workarounds attempted (all failed)

  1. Using setCookie with options:

setCookie(event, 'foo', 'bar', { path: '/', sameSite: 'lax' })

Using appendResponseHeader:

appendResponseHeader(event, 'Set-Cookie', 'foo=bar; Path=/')

  1. Using setResponseHeaders with array:
setResponseHeaders(event, {
  'Set-Cookie': ['foo=bar', 'monkey=trial', 'good=morning']
})
  1. Direct Node.js response manipulation:

event.node.res.setHeader('Set-Cookie', [...])

  1. Using writeHead:
event.node.res.writeHead(200, {
  'Set-Cookie': [...]
})

None of these approaches work - only the last cookie is set.

Additional context

  • Tested on both Nuxt 3.14.159 and 4.1.3 with identical results
  • Tested in fresh projects with no additional configuration
  • Tested with multiple HTTP clients (curl, Postman, browsers)
  • Raw Node.js HTTP server works correctly, confirming this is specific to Nuxt/Nitro

Logs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions