angular/angular-cli · error · Error

Invalid redirect status code: ${status}. Please use one of t

Error message

Invalid redirect status code: ${status}. Please use one of the following redirect response codes: ${[...VALID_REDIRECT_RESPONSE_CODES.values()].join(', ')}.

What it means

`createRedirectResponse` builds an HTTP redirect `Response` for SSR, and only a fixed set of redirect status codes (301, 302, 303, 307, 308 — `VALID_REDIRECT_RESPONSE_CODES`) is allowed. In dev mode (`ngDevMode`) it throws this error if the provided `status` is outside that set, catching invalid redirect codes (e.g. 200 or 404) early.

Source

Thrown at packages/angular/ssr/src/utils/redirect.ts:41

  return VALID_REDIRECT_RESPONSE_CODES.has(code);
}

/**
 * Creates an HTTP redirect response with a specified location and status code.
 *
 * @param location - The URL to which the response should redirect.
 * @param status - The HTTP status code for the redirection. Defaults to 302 (Found).
 *                 See: https://developer.mozilla.org/en-US/docs/Web/API/Response/redirect_static#status
 * @param headers - Additional headers to include in the response.
 * @returns A `Response` object representing the HTTP redirect.
 */
export function createRedirectResponse(
  location: string,
  status = 302,
  headers?: Record<string, string> | Headers,
): Response {
  if (ngDevMode && !isValidRedirectResponseCode(status)) {
    throw new Error(
      `Invalid redirect status code: ${status}. ` +
        `Please use one of the following redirect response codes: ${[...VALID_REDIRECT_RESPONSE_CODES.values()].join(', ')}.`,
    );
  }

  const resHeaders = headers instanceof Headers ? headers : new Headers(headers);
  if (ngDevMode && resHeaders.has('location')) {
    // eslint-disable-next-line no-console
    console.warn(
      `Location header "${resHeaders.get('location')}" will be ignored and set to "${location}".`,
    );
  }

  // Ensure unique values for Vary header
  const varyArray = resHeaders.get('Vary')?.split(',') ?? [];
  const varySet = new Set(['X-Forwarded-Prefix']);
  for (const vary of varyArray) {
    const value = vary.trim();

View on GitHub (pinned to bb72145f9a)

Solutions

  1. Use one of the allowed codes: 301 (permanent), 302 (default temporary), 303, 307, or 308.
  2. Replace invalid codes: use 302/307 for temporary redirects and 301/308 for permanent ones (e.g. change 304 or 200 to 302).
  3. If the status comes from configuration/env, validate/clamp it against `isValidRedirectResponseCode()` before calling.
  4. Note the check only runs when `ngDevMode` is truthy — production builds may silently produce a broken response, so fix at the source, not just in dev.

Example fix

// before
const res = createRedirectResponse(targetUrl, 304);
// after
const res = createRedirectResponse(targetUrl, 302); // or 301/303/307/308
Defensive patterns

Strategy: validation

Validate before calling

const VALID = new Set([301, 302, 303, 307, 308]);
if (!VALID.has(status)) {
  throw new Error(`status must be one of ${[...VALID].join(', ')}, got ${status}`);
}
const res = createRedirectResponse(location, status, headers);

Type guard

function isRedirectStatus(s: number): s is 301 | 302 | 303 | 307 | 308 {
  return [301, 302, 303, 307, 308].includes(s);
}

Try / catch

try {
  return createRedirectResponse(location, status, headers);
} catch (e) {
  if (String(e?.message).startsWith('Invalid redirect status code')) {
    return createRedirectResponse(location, 302, headers); // safe default
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing a custom `status` to `createRedirectResponse(location, status)` (or the underlying redirect helper) that is not one of the valid redirect codes, e.g. `createRedirectResponse('/login', 200)` or a status read from config as an arbitrary number.

Common situations: Language-based redirects (`redirectBasedOnAcceptLanguage`) configured with a wrong default; mapping backend/legacy status codes directly to SSR redirects; typos like 3011 or 304; using 303/308 incorrectly assuming all 3xx are allowed.

Related errors


AI-assisted analysis of angular/angular-cli@bb72145f9a (2026-08-30). Data as JSON: /api/errors/e0099a55866b31b3. Report an issue: GitHub.