denoland/deno · error · Error

ReadRawBytes() failed

Error message

ReadRawBytes() failed

What it means

Deserializer#_readRawBytes(length) asks the op for length bytes; the op returns their offset in the backing store, or a negative value when fewer bytes remain. A negative offset is converted to a plain Error('ReadRawBytes() failed'), meaning the stream is exhausted: the buffer is truncated, or the reader is out of sync with the writer's format.

Source

Thrown at ext/node/polyfills/v8.ts:424

    }
    this.buffer = buffer;
    this[kHandle] = op_v8_new_deserializer(this, buffer);
  }
  readRawBytes(length: number): Buffer {
    const offset = this._readRawBytes(length);
    // `this.buffer` is the Deserializer's own field, not a TypedArray getter.
    // deno-lint-ignore deno-internal/prefer-primordials
    const view = this.buffer;
    return Buffer.from(
      getViewBuffer(view),
      getViewByteOffset(view) + offset,
      length,
    );
  }
  _readRawBytes(length: number): number {
    const offset = op_v8_read_raw_bytes(this[kHandle], length);
    if (offset < 0) {
      throw new Error("ReadRawBytes() failed");
    }
    return offset;
  }
  getWireFormatVersion(): number {
    return op_v8_get_wire_format_version(this[kHandle]);
  }
  readDouble(): number {
    return op_v8_read_double(this[kHandle]);
  }
  readHeader(): boolean {
    return op_v8_read_header(this[kHandle]);
  }

  readUint32(): number {
    return op_v8_read_uint32(this[kHandle]);
  }
  readUint64(): [hi: number, lo: number] {
    return op_v8_read_uint64(this[kHandle]);

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Validate the stream before field reads: readHeader() must return true and getWireFormatVersion() must match the writer's version.
  2. Verify payload completeness before deserializing (length prefix or checksum), especially over sockets.
  3. In custom readers, track the position and check remaining bytes before each readRawBytes call.
  4. Re-serialize data with the current runtime when it originates from another version.

Example fix

// before
const d = new v8.Deserializer(buf);
d.readHeader();
const id = d.readRawBytes(16); // throws if fewer bytes remain

// after
const d = new v8.Deserializer(buf);
if (!d.readHeader() || d.getWireFormatVersion() !== EXPECTED_VERSION) {
  throw new Error("unsupported payload");
}
const id = d.readRawBytes(16);
Defensive patterns

Strategy: try-catch

Validate before calling

const d = new v8.Deserializer(buf);
if (!d.readHeader()) throw new Error("not a v8 serialization stream");

Try / catch

try {
  return decode(payload);
} catch (err) {
  if (String(err?.message).includes("ReadRawBytes() failed")) {
    throw new Error("payload truncated or wire-format mismatch", { cause: err });
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling readRawBytes(n) with n larger than the bytes remaining at the current position — truncated payloads, wire-format drift between runtimes, or a subclass reading fields in the wrong order / without consuming the header first.

Common situations: Deserializing payloads produced by a different Node/V8/Deno version; socket reads that stop at a chunk boundary mid-payload; custom _readHostObject implementations parsing an older layout.

Related errors


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