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
- Change the status to a valid redirect code: 300–308 (typically 302, 303, 307, or 308).
- If you meant to signal a missing page or error, use `error(404, ...)` instead of `redirect`.
- Parse string inputs with `Number(status)` and validate `Number.isInteger(status) && status >= 300 && status <= 308` before calling.
- 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
- Memorize the valid range: 300–308 only.
- Use error() for 4xx/5xx outcomes, redirect() for navigation.
- Coerce and validate any status coming from config, DB, or query strings.
- Prefer named constants (302, 303, 307, 308) over arbitrary numbers.
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
- HTTP error status codes must be between 400 and 599 — ${stat
- Invalid redirect location ${JSON.stringify(location)}: this
- Cannot redirect to external URL ${JSON.stringify(location)}.
- Cannot redirect to ${JSON.stringify(location)} with `{ exter
- ${keypath} cannot be empty
AI-assisted analysis of sveltejs/kit@03f1687fe6 (2026-09-02).
Data as JSON: /api/errors/f80f4f0b7e56a615.
Report an issue: GitHub.