{"record":{"id":"e79b0b013c171ccc","repo":"sveltejs/kit","slug":"failed-to-get-response-header-lower-it-must","errorCode":null,"errorMessage":"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})","messagePattern":"Failed to get response header \"(.+?)\" — it must be included by the `filterSerializedResponseHeaders` option: https://svelte\\.dev/docs/kit/hooks#handle \\(at (.+?)\\)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/kit/src/runtime/server/page/load_data.js","lineNumber":463,"sourceCode":"\t\t\t\t\t\t\tlength: { value: value.length }\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value;\n\t\t\t}\n\t\t});\n\n\t\tif (csr) {\n\t\t\t// ensure that excluded headers can't be read\n\t\t\tconst get = response.headers.get;\n\t\t\tresponse.headers.get = (key) => {\n\t\t\t\tconst lower = key.toLowerCase();\n\t\t\t\tconst value = get.call(response.headers, lower);\n\t\t\t\tif (value && !lower.startsWith('x-sveltekit-')) {\n\t\t\t\t\tconst included = resolve_opts.filterSerializedResponseHeaders(lower, value);\n\t\t\t\t\tif (!included) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`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})`\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn value;\n\t\t\t};\n\n\t\t\tconst get_set_cookie = response.headers.getSetCookie;\n\t\t\tresponse.headers.getSetCookie = () => {\n\t\t\t\tconst values = get_set_cookie.call(response.headers);\n\t\t\t\tfor (const value of values) {\n\t\t\t\t\tconst included = resolve_opts.filterSerializedResponseHeaders('set-cookie', value);\n\t\t\t\t\tif (!included) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`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})`\n\t\t\t\t\t\t);\n\t\t\t\t\t}","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/sveltejs/kit/blob/03f1687fe612ce3d2d9131139b5b188d9cf90c64/packages/kit/src/runtime/server/page/load_data.js#L445-L481","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// hooks.server.js (before)\nfilterSerializedResponseHeaders: () => false;\n// after\nfilterSerializedResponseHeaders: (name) => name.startsWith('x-pagination-');","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const count = res.headers.get('x-total-count');\n  return { items, count: count ? Number(count) : null };\n} catch (e) {\n  if (String(e).includes('filterSerializedResponseHeaders')) {\n    return { items, count: null }; // header not whitelisted\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["sveltekit","headers","load","serialization"],"backgroundTag":"header-not-serialized","analyzedSha":"03f1687fe612ce3d2d9131139b5b188d9cf90c64","analyzedAt":"2026-09-02T02:01:50.504Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}