mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Document is larger than the maximum size

Error message

Document is larger than the maximum size ${this.s.maxBsonObjectSize}

What it means

Thrown as MongoInvalidArgumentError by UnorderedBulkOperation.addToOperationsList() (src/bulk/unordered.ts:60) when a single operation document serializes to a BSON size greater than or equal to maxBsonObjectSize (16 MiB default). Same contract as error 17, but on the unordered bulk path.

Solutions

  1. Move large binary payloads to GridFS or an external object store and keep a reference.
  2. Trim/normalize embedded arrays and deeply nested subdocuments.
  3. Verify db.hello().maxBsonObjectSize on the target server and size accordingly.
  4. Split a huge update into smaller per-field updates or stage the data in a side collection.

Example fix

// before: inline blob blows past 16 MiB
const bulk = coll.initializeUnorderedBulkOp();
bulk.insert({ _id: 1, data: hugeBuffer });
await bulk.execute();

// after: store blob via GridFS, keep only metadata
const bucket = db.bucket();
const streamId = await new Promise((resolve, reject) => {
  const up = bucket.openUploadStream();
  up.end(hugeBuffer, () => resolve(up.id));
  up.on('error', reject);
});
const bulk = coll.initializeUnorderedBulkOp();
bulk.insert({ _id: 1, fileId: streamId });
await bulk.execute();
Defensive patterns

Strategy: validation

Validate before calling

import { serialize } from 'bson';

const MAX_BSON = 16 * 1024 * 1024; // confirm with db.hello().maxBsonObjectSize

function isWithinBsonLimit(doc: unknown): boolean {
  try {
    return serialize(doc as Record<string, unknown>).length < MAX_BSON;
  } catch {
    return false;
  }
}

for (const op of ops) {
  const doc = 'insertOne' in op ? op.insertOne.document : undefined;
  if (doc && !isWithinBsonLimit(doc)) {
    throw new Error('document exceeds 16 MiB BSON limit; move large payloads to GridFS');
  }
}

Type guard

function isReasonablySmallDoc(doc: unknown, max = 16 * 1024 * 1024): boolean {
  try {
    return serialize(doc as Record<string, unknown>).length < max;
  } catch {
    return false;
  }
}

Try / catch

try {
  await bulk.execute();
} catch (e) {
  if (e instanceof MongoInvalidArgumentError && /larger than the maximum size/.test(e.message)) {
    // offload large binary fields to GridFS, then rebuild and re-execute
  } else throw e;
}

Prevention

When it happens

Trigger: Adding an oversized insert/update/replacement document to an unordered bulk op. Guarded by `if (bsonSize >= this.s.maxBsonObjectSize)` at src/bulk/unordered.ts:58.

Common situations: Inline binary blobs instead of GridFS, oversized embedded arrays/nested objects, documents that grew past 16 MiB over time, or targeting a server with a lowered maxBsonObjectSize.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11). Data as JSON: /api/errors/2cfc8e5bcd8da5ac. Report an issue: GitHub.

Appendix: source

Thrown at src/bulk/unordered.ts:60

    if (this.s.usingAutoEncryption) {
      bsonSize = BSON.calculateObjectSize(document, {
        checkKeys: false,
        ignoreUndefined: false
      } as any);
    } else {
      const bson = this.s.bsonOptions;
      buffer = BSON.serialize(document, {
        checkKeys: this.s.checkKeys,
        ignoreUndefined: bson.ignoreUndefined,
        serializeFunctions: bson.serializeFunctions
      });
      bsonSize = buffer.length;
    }

    // Throw error if the doc is bigger than the max BSON size
    if (bsonSize >= this.s.maxBsonObjectSize) {
      // TODO(NODE-3483): Change this to MongoBSONError
      throw new MongoInvalidArgumentError(
        `Document is larger than the maximum size ${this.s.maxBsonObjectSize}`
      );
    }

    // Holds the current batch
    this.s.currentBatch = undefined;
    // Get the right type of batch
    if (batchType === BatchType.INSERT) {
      this.s.currentBatch = this.s.currentInsertBatch;
    } else if (batchType === BatchType.UPDATE) {
      this.s.currentBatch = this.s.currentUpdateBatch;
    } else if (batchType === BatchType.DELETE) {
      this.s.currentBatch = this.s.currentRemoveBatch;
    }

    const maxKeySize = this.s.maxKeySize;

    // Create a new batch object if we don't have a current one

View on GitHub (pinned to dce7939f86)