mongodb/node-mongodb-native · error · MongoUnexpectedServerResponseError
Cursor document did not contain a batch
Error message
Cursor document did not contain a batch
What it means
Thrown by the encryptedBatch getter on CursorResponse when CSFLE/Queryable Encryption is active and the encrypted server response's cursor document contains neither a firstBatch nor a nextBatch array. The driver needs one of these to walk decrypted documents, so it raises a MongoUnexpectedServerResponseError. This path only runs when encryption result decoration is enabled.
Solutions
- Ensure mongodb-client-encryption and libmongocrypt versions match the driver's requirements.
- Upgrade the driver and server to compatible CSFLE/QE-capable releases.
- Disable any proxy that may rewrite encrypted responses.
- Report with the encryption schema and server version if reproducible.
Defensive patterns
Strategy: try-catch
Try / catch
try {
for await (const doc of encryptedCollection.find({})) { }
} catch (error) {
if (error instanceof MongoUnexpectedServerResponseError && /did not contain a batch/.test(error.message)) {
}
} Prevention
- Use mongodb-client-encryption and libmongocrypt versions required by the driver.
- Keep driver, server, and crypt_shared versions aligned.
- Avoid intermediaries that alter encrypted frames.
When it happens
Trigger: Fires at src/cmap/wire_protocol/responses.ts:277 when encryptedResponse is set (CSFLE/QE in use) and `cursor.has('firstBatch')` and `cursor.has('nextBatch')` are both false. Occurs while iterating a cursor whose encrypted payload has an unexpected shape.
Common situations: A malformed encrypted response from the server; mongocrypt/libmongocrypt version incompatibility with the server; a proxy altering the encrypted frame; a server bug in CSFLE/QE response construction. Specific to deployments using client-side encryption.
Related errors
- Expected result of decryption to be deserialized BSON object
- No AutoEncrypter available for encryption
- A collection name must be determined before getMore
- A collection name must be determined before killCursors
- A query document must be specified for query
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/292704aeafdd89d8.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmap/wire_protocol/responses.ts:277
if (namespace != null) return ns(namespace);
return null;
}
public get length() {
return Math.max(this.batchSize - this.iterated, 0);
}
private _encryptedBatch: OnDemandDocument | null = null;
get encryptedBatch() {
if (this.encryptedResponse == null) return null;
if (this._encryptedBatch != null) return this._encryptedBatch;
const cursor = this.encryptedResponse?.get('cursor', BSONType.object);
if (cursor?.has('firstBatch'))
this._encryptedBatch = cursor.get('firstBatch', BSONType.array, true);
else if (cursor?.has('nextBatch'))
this._encryptedBatch = cursor.get('nextBatch', BSONType.array, true);
else throw new MongoUnexpectedServerResponseError('Cursor document did not contain a batch');
return this._encryptedBatch;
}
private get batch() {
if (this._batch != null) return this._batch;
const cursor = this.cursor;
if (cursor.has('firstBatch')) this._batch = cursor.get('firstBatch', BSONType.array, true);
else if (cursor.has('nextBatch')) this._batch = cursor.get('nextBatch', BSONType.array, true);
else throw new MongoUnexpectedServerResponseError('Cursor document did not contain a batch');
return this._batch;
}
public get batchSize() {
return this.batch?.size();
}
public get postBatchResumeToken() {View on GitHub (pinned to dce7939f86)