mongodb/node-mongodb-native · error · MongoOperationTimeoutError

Timed out after ms

Error message

Timed out after ${timeoutMS}ms

What it means

GridFSBucket.delete (src/gridfs/index.ts:162) honors an optional timeoutMS. After deleting the file doc, it checks remainingTimeMS from the CSOT context; if the budget is exhausted it throws MongoOperationTimeoutError before deleting orphaned chunks. This enforces the client-side operation timeout for the delete operation.

Solutions

  1. Increase timeoutMS to a value that comfortably covers both the files and chunks deletions.
  2. Remove timeoutMS for the call if a server-side default (socketTimeoutMS / serverSelectionTimeoutMS) is acceptable.
  3. Investigate server load or indexing that makes the files-collection deleteOne slow.

Example fix

// before
await bucket.delete(id, { timeoutMS: 100 });
// after
await bucket.delete(id, { timeoutMS: 5000 });
Defensive patterns

Strategy: try-catch

Validate before calling

// Estimate budget: delete must cover files + chunks collections.
// Choose a timeout that comfortably exceeds worst-case latency.
function generousTimeout(latencyMs) {
  return Math.max(5000, latencyMs * 4);
}

Type guard

function isTimeoutOption(v: unknown): v is { timeoutMS: number } {
  return v != null && typeof (v as any).timeoutMS === 'number' && (v as any).timeoutMS > 0;
}

Try / catch

try {
  await bucket.delete(id, { timeoutMS });
} catch (e) {
  if (e instanceof MongoOperationTimeoutError && /Timed out/.test(e.message)) {
    // retry with larger timeout or surface to caller
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling bucket.delete(id, { timeoutMS: N }) where the deleteOne on the files collection plus overhead consumes the entire N. A slow or overloaded server causing the files-collection deleteOne to approach the budget.

Common situations: Setting an aggressive timeoutMS that is too small for the operation under load. Network latency or server-side locks consuming the budget before the chunks cleanup runs.

Understand the failure class

Related errors


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

Appendix: source

Thrown at src/gridfs/index.ts:180

  async delete(id: ObjectId, options?: { timeoutMS: number }): Promise<void> {
    const { timeoutMS } = resolveOptions(this.s.db, options);
    let timeoutContext: CSOTTimeoutContext | undefined = undefined;

    if (timeoutMS) {
      timeoutContext = new CSOTTimeoutContext({
        timeoutMS,
        serverSelectionTimeoutMS: this.s.db.client.s.options.serverSelectionTimeoutMS
      });
    }

    const { deletedCount } = await this.s._filesCollection.deleteOne(
      { _id: id },
      { timeoutMS: timeoutContext?.remainingTimeMS }
    );

    const remainingTimeMS = timeoutContext?.remainingTimeMS;
    if (remainingTimeMS != null && remainingTimeMS <= 0)
      throw new MongoOperationTimeoutError(`Timed out after ${timeoutMS}ms`);
    // Delete orphaned chunks before returning FileNotFound
    await this.s._chunksCollection.deleteMany({ files_id: id }, { timeoutMS: remainingTimeMS });

    if (deletedCount === 0) {
      // TODO(NODE-3483): Replace with more appropriate error
      // Consider creating new error MongoGridFSFileNotFoundError
      throw new MongoRuntimeError(`File not found for id ${id}`);
    }
  }

  /** Convenience wrapper around find on the files collection */
  find(filter: Filter<GridFSFile> = {}, options: FindOptions = {}): FindCursor<GridFSFile> {
    return this.s._filesCollection.find(filter, options);
  }

  /**
   * Returns a readable stream (GridFSBucketReadStream) for streaming the
   * file with the given name from GridFS. If there are multiple files with

View on GitHub (pinned to dce7939f86)