sveltejs/kit · error · Error

Use `event.cookies.set(name, value, options)` instead of `ev

Error message

Use `event.cookies.set(name, value, options)` instead of `event.setHeaders` to set cookies

What it means

`event.setHeaders` manipulates the response's plain headers object, but cookies must go through the cookie jar so they merge with SvelteKit-managed cookies (auth, CSRF, etc.). Setting `set-cookie` via setHeaders would overwrite or conflict with the jar, so it throws immediately.

Source

Thrown at packages/kit/src/runtime/server/respond.js:217

		platform: state.emulator?.platform
			? await state.emulator.platform({
					config: {},
					prerender: !!state.prerendering?.fallback
				})
			: state.platform,
		request,
		route: { id: null },
		setHeaders: (new_headers) => {
			if (DEV) {
				validateHeaders(new_headers);
			}

			for (const key in new_headers) {
				const lower = key.toLowerCase();
				const value = new_headers[key];

				if (lower === 'set-cookie') {
					throw new Error(
						'Use `event.cookies.set(name, value, options)` instead of `event.setHeaders` to set cookies'
					);
				} else if (lower in headers) {
					// appendHeaders-style for Server-Timing https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Server-Timing
					if (lower === 'server-timing') {
						headers[lower] += ', ' + value;
					} else {
						throw new Error(`"${key}" header is already set`);
					}
				} else {
					headers[lower] = value;

					if (state.prerendering && lower === 'cache-control') {
						state.prerendering.cache = /** @type {string} */ (value);
					}
				}
			}
		},

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Replace `event.setHeaders({ 'set-cookie': ... })` with `event.cookies.set(name, value, options)`
  2. For multiple cookies, call event.cookies.set once per cookie
  3. For deleting cookies, use event.cookies.delete(name, options)

Example fix

// before
event.setHeaders({ 'set-cookie': 'session=abc; Path=/; HttpOnly' });
// after
event.cookies.set('session', 'abc', { path: '/', httpOnly: true });
Defensive patterns

Strategy: validation

Validate before calling

function assertNoSetCookie(headers) {
  if (Object.keys(headers).some((k) => k.toLowerCase() === 'set-cookie')) {
    throw new Error('use event.cookies.set for cookies');
  }
}

Prevention

When it happens

Trigger: In a `handle` hook, `load`, or action, code calls `event.setHeaders({ 'set-cookie': '...' })` (any key casing), triggering the `lower === 'set-cookie'` branch in internal_respond's header application.

Common situations: Porting Express middleware that sets cookies via headers; copying code that sets session cookies with setHeaders; framework migration where the cookies API was introduced after the code was written.

Related errors


AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02). Data as JSON: /api/errors/2c6709404f9c96a5. Report an issue: GitHub.