sveltejs/kit · warning

location header missing on redirect received from ${decoded}

Error message

location header missing on redirect received from ${decoded}

What it means

During prerendering, when a response with a redirect status (3xx) is received but no `location` header is present, prerender.js logs this warning and skips saving the redirect. SvelteKit cannot record a redirect without a target URL.

Source

Thrown at packages/kit/src/core/postbuild/prerender.js:586

						)};</script><meta http-equiv="refresh" content="${escape_html(
							`0;url=${location}`,
							true
						)}">`
					);

					written.add(file);

					if (!prerendered.redirects.has(decoded)) {
						prerendered.redirects.set(decoded, {
							status: response.status,
							location: resolved
						});

						prerendered.paths.push(decoded);
					}
				}
			} else {
				log.warn(`location header missing on redirect received from ${decoded}`);
			}

			return;
		}

		if (response.status === 200) {
			if (existsSync(dest) && statSync(dest).isDirectory()) {
				throw new Error(
					`Cannot save ${decoded} as it is already a directory. See https://svelte.dev/docs/kit/page-options#prerender-route-conflicts for more information`
				);
			}

			const dir = dirname(dest);

			if (existsSync(dir) && !statSync(dir).isDirectory()) {
				const parent = decoded.split('/').slice(0, -1).join('/');
				throw new Error(
					`Cannot save ${decoded} as ${parent} is already a file. See https://svelte.dev/docs/kit/page-options#prerender-route-conflicts for more information`

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Use `redirect(status, location)` from `$app/navigation`/`@sveltejs/kit` in `+server.js` and load functions so the Location header is set
  2. If building a raw Response, include `headers: { location: '/target' }`
  3. Ensure any conditional redirect logic always has a non-empty target URL

Example fix

// before
return new Response(null, { status: 302 });
// after
import { redirect } from '@sveltejs/kit';
return redirect(302, '/login'); // or new Response(null, { status: 302, headers: { location: '/login' } })
Defensive patterns

Strategy: validation

Validate before calling

// endpoint guard before returning a manual redirect response
if (res.status >= 300 && res.status < 400 && !res.headers.get('location')) {
  throw new Error('redirect response missing location header');
}

Type guard

/** @returns {res is Response & { headers: Headers & { get(k: 'location'): string } }} */
function hasLocation(res) { return res.status >= 300 && res.status < 400 && !!res.headers.get('location'); }

Prevention

When it happens

Trigger: A prerendered page (or endpoint) returns status 301/302/307/308 from `+server.js` or a `load` redirect without setting the `location` header, e.g. `redirect(302)` misuse or a hand-built `Response` with `status: 302` but no `Location` header.

Common situations: Manually constructing `new Response(null, { status: 302 })` in a prerendered endpoint; server-side redirects computed from missing env data; proxy responses stripped of headers.

Related errors


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