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

  1. Pass a positive integer in 1..4294967295, odd and larger than the current nextStreamID for client sessions
  2. If you only need 'the next odd id', pass id = lastStreamID + 2 and verify it stays under 2**32
  3. 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

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


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/82c523dd899e4d86. Report an issue: GitHub.