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

  1. Ensure mongodb-client-encryption and libmongocrypt versions match the driver's requirements.
  2. Upgrade the driver and server to compatible CSFLE/QE-capable releases.
  3. Disable any proxy that may rewrite encrypted responses.
  4. 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

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


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)