denoland/deno · error · RangeError
ERR_OUT_OF_RANGE
ERR_OUT_OF_RANGE
Error message
The value of "id" is out of range. It must be > 0 and <= ${kMaxStreams}. Received ${id} What it means
setNextStreamID() validates that id is a number strictly greater than 0 and at most kMaxStreams (2**32 - 1 = 4294967295), the full 32-bit HTTP/2 stream-ID space. The message interpolates both bounds. Note that validateNumber() runs first, so a non-number or NaN fails earlier with ERR_INVALID_ARG_TYPE, and nghttp2 additionally requires client-initiated stream IDs to be odd.
Source
Thrown at ext/node/polyfills/http2.ts:4157
return;
}
if (this[kTimeout]) {
this[kTimeout].refresh();
syncSessionTimeoutInspectLinks(this[kTimeout]);
}
}
// Sets the id of the next stream to be created by this Http2Session.
// The value must be a number in the range 0 <= n <= kMaxStreams. The
// value also needs to be larger than the current next stream ID.
setNextStreamID(id) {
if (this.destroyed) {
throw new ERR_HTTP2_INVALID_SESSION();
}
validateNumber(id, "id");
if (id <= 0 || id > kMaxStreams) {
throw new ERR_OUT_OF_RANGE("id", `> 0 and <= ${kMaxStreams}`, id);
}
this[kHandle].setNextStreamID(id);
}
// Sets the local window size (local endpoints's window size)
// Returns 0 if success or throw an exception if NGHTTP2_ERR_NOMEM
// if the window allocation fails
setLocalWindowSize(windowSize) {
if (this.destroyed) {
throw new ERR_HTTP2_INVALID_SESSION();
}
validateInt32(windowSize, "windowSize", 0);
const ret = this[kHandle].setLocalWindowSize(windowSize);
if (ret === NGHTTP2_ERR_NOMEM) {
this.destroy(new Error("HTTP2 session out of memory"));
}View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Pass a positive integer in 1..4294967295, odd and larger than the current nextStreamID for client sessions
- If you only need 'the next odd id', pass id = lastStreamID + 2 and verify it stays under 2**32
- Clamp or reject the computed id before calling setNextStreamID
Example fix
// before session.setNextStreamID(0); // after const kMaxStreams = 2 ** 32 - 1; if (nextId > 0 && nextId <= kMaxStreams) session.setNextStreamID(nextId);
Defensive patterns
Strategy: validation
Validate before calling
const kMaxStreams = 2 ** 32 - 1;
if (!Number.isInteger(id) || id <= 0 || id > kMaxStreams) {
throw new RangeError(`bad next stream id: ${id}`);
}
session.setNextStreamID(id); Type guard
function isValidStreamId(id) {
return Number.isInteger(id) && id > 0 && id <= 2 ** 32 - 1;
} Prevention
- Client-initiated stream IDs must be odd — compute nextId as lastOddId + 2
- Range-check computed IDs before calling; overflow past 2**32 is a bug in the caller's math
- Never seed from a zero-based counter
When it happens
Trigger: session.setNextStreamID(0), a negative id, a fractional id like 1.5, or any value above 4294967295; also computing the next id with an overflow or bitwise expression that wraps past 2**32.
Common situations: Seeding the id from a counter that starts at 0; deriving it via (lastId * 2) growth that overflows 32 bits; copying server-side even IDs into a client session where odd IDs are required anyway.
Related errors
- ERR_INVALID_ARG_VALUE
- ERR_INVALID_ARG_TYPE
- ERR_HTTP2_INVALID_INFO_STATUS
- ERR_HTTP2_PING_LENGTH
- ERR_INVALID_CHAR
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/82c523dd899e4d86.
Report an issue: GitHub.