expressjs/express · error · RangeError

Invalid status code: ${JSON.stringify(code)}. Status code mu

Error message

Invalid status code: ${JSON.stringify(code)}. Status code must be greater than 99 and less than 1000.

What it means

Thrown by Express's `res.status(code)` when the integer status code is outside the range 100–999 that Node's HTTP layer accepts. Express validates before assigning `this.statusCode` so the failure surfaces at the call site instead of deep inside Node when headers are written. A separate TypeError covers non-integer input; this RangeError covers out-of-range integers.

Source

Thrown at lib/response.js:72

 *
 * Expects an integer value between 100 and 999 inclusive.
 * Throws an error if the provided status code is not an integer or if it's outside the allowable range.
 *
 * @param {number} code - The HTTP status code to set.
 * @return {ServerResponse} - Returns itself for chaining methods.
 * @throws {TypeError} If `code` is not an integer.
 * @throws {RangeError} If `code` is outside the range 100 to 999.
 * @public
 */

res.status = function status(code) {
  // Check if the status code is not an integer
  if (!Number.isInteger(code)) {
    throw new TypeError(`Invalid status code: ${JSON.stringify(code)}. Status code must be an integer.`);
  }
  // Check if the status code is outside of Node's valid range
  if (code < 100 || code > 999) {
    throw new RangeError(`Invalid status code: ${JSON.stringify(code)}. Status code must be greater than 99 and less than 1000.`);
  }

  this.statusCode = code;
  return this;
};

/**
 * Set Link header field with the given `links`.
 *
 * Examples:
 *
 *    res.links({
 *      next: 'http://api.example.com/users?page=2',
 *      last: 'http://api.example.com/users?page=5',
 *      pages: [
 *        'http://api.example.com/users?page=1',
 *        'http://api.example.com/users?page=2'
 *      ]

View on GitHub ↗ (pinned to a3714473fe)

Solutions

  1. Validate or clamp the code before calling res.status — map internal error codes to real HTTP statuses (e.g. default to 500).
  2. When proxying upstream responses, only forward `upstream.status` if it is between 100 and 999; otherwise use 502.
  3. If the value comes from `err.status`/`err.statusCode`, fall back: `res.status(Number.isInteger(err.status) && err.status >= 100 && err.status <= 999 ? err.status : 500)`.

Example fix

// before
res.status(upstreamError.code).send('failed'); // code was 0
// after
const status = Number.isInteger(upstreamError.code) && upstreamError.code >= 100 && upstreamError.code <= 999 ? upstreamError.code : 500;
res.status(status).send('failed');
Defensive patterns

Strategy: validation

Validate before calling

const code = Number(status);
if (!Number.isInteger(code) || code < 100 || code > 999) {
  throw new Error(`Refusing invalid HTTP status: ${status}`);
}
res.status(code).send(body);

Type guard

function isValidStatusCode(code) {
  return Number.isInteger(code) && code >= 100 && code <= 999;
}

Prevention

When it happens

Trigger: Calling `res.status(code)` (or `res.sendStatus`) with an integer < 100 or > 999, e.g. `res.status(0)`, `res.status(99)`, `res.status(1000)`, or a computed/derived code that fell out of range.

Common situations: Passing an upstream service's error code or exit code straight through as an HTTP status; using a database/application error number as a status; arithmetic on status codes producing 0; forwarding `err.status` that was never set on custom errors after coercion.

Related errors


AI-assisted analysis of expressjs/express@a3714473fe (2026-07-31). Data as JSON: /data/errors/f3aa1efa9344d369.json. Report an issue: GitHub ↗.