mongodb/node-mongodb-native · critical · RangeError
OP_REPLY numberReturned is an invalid array length
Error message
OP_REPLY numberReturned is an invalid array length ${this.numberReturned} What it means
Thrown as a RangeError in OpReply.parse() when the numberReturned field read from an OP_REPLY message is negative or exceeds 2^32-1. numberReturned tells the driver how many BSON documents follow in the reply; an out-of-range value would either allocate a huge array or loop a negative number of times. This indicates the wire message is corrupt or was truncated/mis-parsed.
Solutions
- Check for a proxy or load balancer between the client and server that may corrupt traffic
- Verify network/TLS integrity; try without compression (compressors=[]) to isolate
- Upgrade the MongoDB server to a version that uses OP_MSG (3.6+)
- Report to the driver team with a packet capture if the server is a genuine MongoDB instance
Defensive patterns
Strategy: try-catch
Try / catch
try { await client.connect(); } catch (e) {
if (e instanceof RangeError && /OP_REPLY numberReturned/.test(e.message)) {
// suspect wire-protocol corruption; check proxies/TLS, try a different endpoint
}
throw e;
} Prevention
- Avoid proxies that mangle the MongoDB wire protocol
- Prefer MongoDB 3.6+ servers that speak OP_MSG instead of legacy OP_REPLY
- Investigate recurring corruption with a packet capture
When it happens
Trigger: Receiving an OP_REPLY (legacy, pre-3.2 servers or certain monitoring replies) where the 4-byte numberReturned field at offset 16 is < 0 or > 4294967295. Caused by network corruption, a man-in-the-middle, a buggy/proxy server, or a truncated TCP read.
Common situations: Connecting through a misbehaving proxy (HAProxy, mongo-proxy) that mangles the wire protocol; a corrupted TLS session; a server version so old it still uses OP_REPLY; cosmic-ray bit flips (rare).
Related errors
- Message body and message header must be the same length
- Binary type with subtype 0x02 contains too long binary size
- Binary type with subtype 0x02 contains too short binary size
- Negative binary type element size found for subtype 0x02
- OP_MSG Payload Type 1 detected unsupported protocol
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/8e582ae1f99c502a.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmap/commands.ts:381
return this.parsed;
}
parse(): Uint8Array {
// Don't parse again if not needed
if (this.parsed) return this.sections[0];
// Position within OP_REPLY at which documents start
// (See https://www.mongodb.com/docs/manual/reference/mongodb-wire-protocol/#wire-op-reply)
this.index = 20;
// Read the message body
this.responseFlags = readInt32LE(this.data, 0);
this.cursorId = new BSON.Long(readInt32LE(this.data, 4), readInt32LE(this.data, 8));
this.startingFrom = readInt32LE(this.data, 12);
this.numberReturned = readInt32LE(this.data, 16);
if (this.numberReturned < 0 || this.numberReturned > 2 ** 32 - 1) {
throw new RangeError(
`OP_REPLY numberReturned is an invalid array length ${this.numberReturned}`
);
}
this.cursorNotFound = (this.responseFlags & CURSOR_NOT_FOUND) !== 0;
this.queryFailure = (this.responseFlags & QUERY_FAILURE) !== 0;
this.shardConfigStale = (this.responseFlags & SHARD_CONFIG_STALE) !== 0;
this.awaitCapable = (this.responseFlags & AWAIT_CAPABLE) !== 0;
// Parse Body
for (let i = 0; i < this.numberReturned; i++) {
const bsonSize =
this.data[this.index] |
(this.data[this.index + 1] << 8) |
(this.data[this.index + 2] << 16) |
(this.data[this.index + 3] << 24);
const section = this.data.subarray(this.index, this.index + bsonSize);View on GitHub (pinned to dce7939f86)