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
- Validate or clamp the code before calling res.status — map internal error codes to real HTTP statuses (e.g. default to 500).
- When proxying upstream responses, only forward `upstream.status` if it is between 100 and 999; otherwise use 502.
- 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
- Never pass user- or upstream-derived values directly to res.status(); map them through an allowlist of statuses your app actually uses
- Coerce with Number() and check Number.isInteger before calling res.status
- Centralize error-to-status mapping in one helper so the range check lives in exactly one place
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
- Status must be a number
- ECONNABORTED
- name argument is required to req.get
- name must be a string to req.get
- app.use() requires a middleware function
AI-assisted analysis of expressjs/express@a3714473fe (2026-07-31).
Data as JSON: /data/errors/f3aa1efa9344d369.json.
Report an issue: GitHub ↗.