sveltejs/kit · error · Error
Failed to get response header "set-cookie" — it must be incl
Error message
Failed to get response header "set-cookie" — it must be included by the `filterSerializedResponseHeaders` option: https://svelte.dev/docs/kit/hooks#handle (at ${event.route.id}) What it means
During SSR, SvelteKit wraps a `fetch` response's `headers.getSetCookie` so it can serialize cookies into the page data. Before returning the values it consults the `filterSerializedResponseHeaders` option in your `handle` hook; if the callback returns false for 'set-cookie', the error is thrown instead of silently dropping cookies.
Source
Thrown at packages/kit/src/runtime/server/page/load_data.js:478
if (value && !lower.startsWith('x-sveltekit-')) {
const included = resolve_opts.filterSerializedResponseHeaders(lower, value);
if (!included) {
throw new Error(
`Failed to get response header "${lower}" — it must be included by the \`filterSerializedResponseHeaders\` option: https://svelte.dev/docs/kit/hooks#handle (at ${event.route.id})`
);
}
}
return value;
};
const get_set_cookie = response.headers.getSetCookie;
response.headers.getSetCookie = () => {
const values = get_set_cookie.call(response.headers);
for (const value of values) {
const included = resolve_opts.filterSerializedResponseHeaders('set-cookie', value);
if (!included) {
throw new Error(
`Failed to get response header "set-cookie" — it must be included by the \`filterSerializedResponseHeaders\` option: https://svelte.dev/docs/kit/hooks#handle (at ${event.route.id})`
);
}
}
return values;
};
}
return proxy;
};
// Don't make this function `async`! Otherwise, the user has to `catch` promises they use for streaming responses or else
// it will be an unhandled rejection. Instead, we add a `.catch(noop)` ourselves below to this from happening.
return (input, init) => {
// See docs in fetch.js for why we need to do this
const response = universal_fetch(input, init);
response.catch(noop);View on GitHub (pinned to 03f1687fe6)
Solutions
- Update `filterSerializedResponseHeaders` in the `handle` hook to return true for 'set-cookie' when the value should be serialized
- If cookies must not leak, stop reading set-cookie from that proxied fetch response and pass session info another way
- Guard the header read so getSetCookie is only called when the filter allows it
Example fix
// before filterSerializedResponseHeaders: (name) => name !== 'set-cookie' // after filterSerializedResponseHeaders: (name) => name === 'set-cookie' || name === 'content-type'
Defensive patterns
Strategy: validation
Validate before calling
// in handle hook const filterSerializedResponseHeaders = (name, value) => name === 'set-cookie' ? shouldSerializeCookie(value) : true;
Prevention
- Make filterSerializedResponseHeaders allow set-cookie for trusted internal APIs
- Only read set-cookie from load-time fetches that you intend to serialize
- Document which proxied endpoints are allowed to forward cookies
When it happens
Trigger: A `load` function calls SvelteKit's `fetch` on an API whose response contains a `set-cookie` header, while the app's `handle` hook supplies a `filterSerializedResponseHeaders` callback that returns false for ('set-cookie', value), and the code then reads cookies via the wrapped getSetCookie during serialization.
Common situations: Apps that intentionally strip cookies from internal API responses but still have a load function that touches response cookies (e.g. reading session cookies from a backend); developers copying an example `filterSerializedResponseHeaders: (name) => name !== 'set-cookie'` without realizing serialized load data needs the header allowed.
Related errors
- Cannot call `fetch` eagerly during server-side rendering wit
- Use `event.cookies.set(name, value, options)` instead of `ev
- Loading ${url} using `window.fetch`. For best results, use t
- Avoid calling `fetch` eagerly during server-side rendering —
- Cannot access cloudflare:workers in a prerenderable route
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/e511a85d58072027.
Report an issue: GitHub.