mongodb/node-mongodb-native · error · MongoOperationTimeoutError

Timed out after ${timeoutMS}ms

Error message

Timed out after ${timeoutMS}ms

What it means

A MongoOperationTimeoutError raised by GridFSBucket.delete() when the cumulative time spent (after deleting the files doc) leaves no budget for the orphaned-chunks cleanup, per CSOT semantics. The message reports the original timeoutMS that was requested.

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 3366c21a63)

Solutions

  1. Increase timeoutMS for deletes of large GridFS files
  2. Drop timeoutMS for this op if CSOT isn't strictly required
  3. Ensure an index exists on chunks.files_id so deleteMany is fast
  4. Move large deletes off peak load

Example fix

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

Strategy: try-catch

Try / catch

try {
  await bucket.delete(id, { timeoutMS });
} catch (err) {
  if (err instanceof MongoOperationTimeoutError) {
    await bucket.delete(id, { timeoutMS: timeoutMS * 4 }); // retry idempotent delete with larger budget
  } else throw err;
}

Prevention

When it happens

Trigger: await bucket.delete(id, { timeoutMS: 50 }) where deleteOne + deleteMany cannot both finish in time, or the remaining budget hits zero between the two steps.

Common situations: Aggressive timeoutMS on large files; slow or overloaded server; missing index on chunks.files_id; high-latency network.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04). Data as JSON: /data/errors/3da03eb7500056ec.json. Report an issue: GitHub.