sveltejs/kit · error

Invalid status code

Error message

Invalid status code

What it means

`redirect()` validates its status argument before constructing a `Redirect` object. SvelteKit requires redirect statuses to be in the 300–308 range; anything else (NaN, below 300, above 308) cannot be used as an HTTP redirect, so the library throws immediately in dev or on the server. This check is skipped in a production browser build since the status was already validated server-side.

Source

Thrown at packages/kit/src/exports/index.js:131

 * Make sure you're not catching the thrown redirect, which would prevent SvelteKit from handling it.
 *
 * Most common status codes:
 *  * `303 See Other`: redirect as a GET request (often used after a form POST request)
 *  * `307 Temporary Redirect`: redirect will keep the request method
 *  * `308 Permanent Redirect`: redirect will keep the request method, SEO will be transferred to the new page
 *
 * [See all redirect status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages)
 *
 * @param {300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | ({} & number)} status The [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#redirection_messages). Must be in the range 300-308.
 * @param {string | URL} location The location to redirect to.
 * @param {{ external?: boolean | string[] }} [options] To redirect to an external URL, you must pass `{ external: true }` to allow any external URL except `javascript:` URLs, or `{ external: [...] }` with an allowlist of permitted origins.
 * @throws {import('./public.js').Redirect} This error instructs SvelteKit to redirect to the specified location.
 * @throws {Error} If the provided status is invalid, the location cannot be used as a header value, or the location is an external URL without permission.
 * @return {never}
 */
export function redirect(status, location, options) {
	if ((!BROWSER || DEV) && (isNaN(status) || status < 300 || status > 308)) {
		throw new Error('Invalid status code');
	}

	const href = location.toString();
	validate_redirect_location(href, options);

	throw new Redirect(
		// @ts-ignore
		status,
		href
	);
}

/**
 * Checks whether this is a redirect thrown by {@link redirect}.
 * @param {unknown} e The object to check.
 * @return {e is import('./public.js').Redirect}
 */
export function isRedirect(e) {

View on GitHub (pinned to 03f1687fe6)

Solutions

  1. Change the status to a valid redirect code: 300–308 (typically 302, 303, 307, or 308).
  2. If you meant to signal a missing page or error, use `error(404, ...)` instead of `redirect`.
  3. Parse string inputs with `Number(status)` and validate `Number.isInteger(status) && status >= 300 && status <= 308` before calling.
  4. For client-side navigation within a component, consider `goto()` instead of a raw redirect.

Example fix

// before
redirect(response.status, '/login');
// after
redirect(response.status >= 300 && response.status <= 308 ? response.status : 302, '/login');
Defensive patterns

Strategy: validation

Validate before calling

function isValidRedirectStatus(s) {
  return Number.isInteger(s) && s >= 300 && s <= 308;
}
if (!isValidRedirectStatus(status)) status = 302;

Type guard

const isRedirectStatus = (s) => typeof s === 'number' && Number.isInteger(s) && s >= 300 && s <= 308;

Try / catch

try {
  redirect(status, location);
} catch (e) {
  if (e.message === 'Invalid status code') redirect(302, location);
  else throw e;
}

Prevention

When it happens

Trigger: Calling `redirect(200, '/other')`, `redirect(404, '/missing')`, `redirect(0, ...)`, or passing a non-numeric string/variable that coerces to NaN. Also calling redirect with a variable status computed at runtime that falls outside 300–308.

Common situations: Confusing `redirect` with `error()` and using 404/500 statuses; using 301/302 which are fine but using 200 or 299 by mistake; passing `event.url.searchParams.get('status')` (a string) directly, yielding NaN.

Related errors


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