sveltejs/kit · error · Error
Failed to get response header "${lower}" — it must be includ
Error message
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}) What it means
During server-side rendering, universal-load fetch responses are serialized to the client with only a whitelisted set of headers. Reading a header via `response.headers.get()` that `filterSerializedResponseHeaders` (in `handle` in hooks.server.js) doesn't approve throws this error, since the header would be absent on the client and cause hydration mismatches.
Source
Thrown at packages/kit/src/runtime/server/page/load_data.js:463
length: { value: value.length }
}
);
}
return value;
}
});
if (csr) {
// ensure that excluded headers can't be read
const get = response.headers.get;
response.headers.get = (key) => {
const lower = key.toLowerCase();
const value = get.call(response.headers, lower);
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})`
);
}View on GitHub (pinned to 03f1687fe6)
Solutions
- In hooks.server.js `handle`, set `event.setHeaders` appropriately and add the header name to `filterSerializedResponseHeaders`: return true for the headers you need serialized
- Move the fetch to a server-only load (`+page.server.js`) where headers are fully accessible
- Read the data via your own `+server.js` proxy that returns the value in the JSON body instead of a header
Example fix
// hooks.server.js (before)
filterSerializedResponseHeaders: () => false;
// after
filterSerializedResponseHeaders: (name) => name.startsWith('x-pagination-'); Defensive patterns
Strategy: try-catch
Try / catch
try {
const count = res.headers.get('x-total-count');
return { items, count: count ? Number(count) : null };
} catch (e) {
if (String(e).includes('filterSerializedResponseHeaders')) {
return { items, count: null }; // header not whitelisted
}
throw e;
} Prevention
- Whitelist every header you read from cross-origin fetches in `filterSerializedResponseHeaders` in hooks.server.js
- Prefer returning needed metadata in the JSON body over relying on headers
- Use server-only loads when you need unrestricted header access
When it happens
Trigger: Calling `response.headers.get('some-header')` inside a universal load on a cross-origin fetch where `filterSerializedResponseHeaders(name, value)` returns false (default rejects all non-`x-sveltekit-` headers).
Common situations: Reading `ratelimit-*`, `x-total-count`, or custom pagination headers from an API in `+page.js` load; forgetting to add the header to the whitelist in `handle` in hooks.server.js after adding new header reads.
Related errors
- a load function ${location_description} returned ${typeof da
- Data returned from action inside ${route_id} is not serializ
- Data returned from action inside ${route_id} is not serializ
- Loading ${url} using `window.fetch`. For best results, use t
- Could not deserialize binary form: file offset table too sho
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/e79b0b013c171ccc.
Report an issue: GitHub.