{"record":{"id":"8e582ae1f99c502a","repo":"mongodb/node-mongodb-native","slug":"op-reply-numberreturned-is-an-invalid-array-length","errorCode":null,"errorMessage":"OP_REPLY numberReturned is an invalid array length ${this.numberReturned}","messagePattern":"OP_REPLY numberReturned is an invalid array length (.+?)","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"critical","filePath":"src/cmap/commands.ts","lineNumber":381,"sourceCode":"    return this.parsed;\n  }\n\n  parse(): Uint8Array {\n    // Don't parse again if not needed\n    if (this.parsed) return this.sections[0];\n\n    // Position within OP_REPLY at which documents start\n    // (See https://www.mongodb.com/docs/manual/reference/mongodb-wire-protocol/#wire-op-reply)\n    this.index = 20;\n\n    // Read the message body\n    this.responseFlags = readInt32LE(this.data, 0);\n    this.cursorId = new BSON.Long(readInt32LE(this.data, 4), readInt32LE(this.data, 8));\n    this.startingFrom = readInt32LE(this.data, 12);\n    this.numberReturned = readInt32LE(this.data, 16);\n\n    if (this.numberReturned < 0 || this.numberReturned > 2 ** 32 - 1) {\n      throw new RangeError(\n        `OP_REPLY numberReturned is an invalid array length ${this.numberReturned}`\n      );\n    }\n\n    this.cursorNotFound = (this.responseFlags & CURSOR_NOT_FOUND) !== 0;\n    this.queryFailure = (this.responseFlags & QUERY_FAILURE) !== 0;\n    this.shardConfigStale = (this.responseFlags & SHARD_CONFIG_STALE) !== 0;\n    this.awaitCapable = (this.responseFlags & AWAIT_CAPABLE) !== 0;\n\n    // Parse Body\n    for (let i = 0; i < this.numberReturned; i++) {\n      const bsonSize =\n        this.data[this.index] |\n        (this.data[this.index + 1] << 8) |\n        (this.data[this.index + 2] << 16) |\n        (this.data[this.index + 3] << 24);\n\n      const section = this.data.subarray(this.index, this.index + bsonSize);","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/mongodb/node-mongodb-native/blob/dce7939f86fb283e167ad709955abedb7bf23124/src/cmap/commands.ts#L363-L399","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await client.connect(); } catch (e) {\n  if (e instanceof RangeError && /OP_REPLY numberReturned/.test(e.message)) {\n    // suspect wire-protocol corruption; check proxies/TLS, try a different endpoint\n  }\n  throw e;\n}","preventionTips":["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"],"tags":["wire-protocol","op-reply","corruption","network"],"backgroundTag":null,"analyzedSha":"dce7939f86fb283e167ad709955abedb7bf23124","analyzedAt":"2026-08-11T04:54:53.215Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}