denoland/deno · error · RangeError

ERR_BUFFER_OUT_OF_BOUNDS

ERR_BUFFER_OUT_OF_BOUNDS

Error message

"offset" is outside of buffer bounds

What it means

In sliceBuffer(), after offset is coerced with 'offset >>> 0' it must not exceed buffer.byteLength, otherwise ERR_BUFFER_OUT_OF_BOUNDS('offset') is thrown. The >>> 0 coercion means a negative offset becomes a huge uint32 and virtually always fails this check.

Source

Thrown at ext/node/polyfills/dgram.ts:1473

}

function sliceBuffer(buffer: MessageType, offset: number, length: number) {
  if (typeof buffer === "string") {
    buffer = Buffer.from(buffer);
  } else if (!isArrayBufferView(buffer)) {
    throw new ERR_INVALID_ARG_TYPE(
      "buffer",
      ["Buffer", "TypedArray", "DataView", "string"],
      buffer,
    );
  }

  offset = offset >>> 0;
  length = length >>> 0;

  // deno-lint-ignore deno-internal/prefer-primordials -- buffer may be a Buffer or DataView, not a plain TypedArray
  if (offset > buffer.byteLength) {
    throw new ERR_BUFFER_OUT_OF_BOUNDS("offset");
  }

  // deno-lint-ignore deno-internal/prefer-primordials -- buffer may be a Buffer or DataView, not a plain TypedArray
  if (offset + length > buffer.byteLength) {
    throw new ERR_BUFFER_OUT_OF_BOUNDS("length");
  }

  // deno-lint-ignore deno-internal/prefer-primordials -- Buffer is the Node Buffer class; .buffer/.byteOffset on a Buffer or DataView
  return Buffer.from(buffer.buffer, buffer.byteOffset + offset, length);
}

function fixBufferList(
  list: ReadonlyArray<MessageType>,
): Array<MessageType> | null {
  const newList = new Array(list.length);

  for (let i = 0, l = list.length; i < l; i++) {
    const buf = list[i];

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Clamp before calling: offset = Math.max(0, Math.min(offset, buf.byteLength))
  2. Validate the packet actually contains the header: if (buf.length < HEADER_LEN) drop/ignore it
  3. Remember offset is in bytes and is uint32-coerced — negatives are never valid

Example fix

// before
sock.send(pkt, 12, pkt.length - 12, port, host); // throws when pkt.length < 12

// after
if (pkt.length < 12) return; // or handle short packet
sock.send(pkt, 12, pkt.length - 12, port, host);
Defensive patterns

Strategy: validation

Validate before calling

const off = offset >>> 0;
if (!(off <= buffer.byteLength)) {
  throw new RangeError(`offset ${offset} out of bounds for ${buffer.byteLength} bytes`);
}
sock.send(buffer, off, length, port, host, cb);

Prevention

When it happens

Trigger: sock.send(buf, 2048, 10, port, host) with a 1024-byte buffer; sock.send(buf, -8, 16, port) (becomes 0xFFFFFFF8 after >>> 0); offsets computed from a header size larger than the payload.

Common situations: Offsets from protocol headers (e.g. skipping a 12-byte DNS header on short packets); arithmetic that goes negative on truncated data; using bit offsets instead of byte offsets.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/2a47a549773d38f3. Report an issue: GitHub.