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 withView on GitHub (pinned to 3366c21a63)
Solutions
- Increase timeoutMS for deletes of large GridFS files
- Drop timeoutMS for this op if CSOT isn't strictly required
- Ensure an index exists on chunks.files_id so deleteMany is fast
- 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
- Size timeoutMS to file size and chunk count
- Ensure the chunks collection is indexed on files_id
- Retry idempotent deletes with a larger budget
- Move large GridFS deletes off peak load
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
- KMS request timed out
- Server roundtrip time is greater than the time remaining
- Server reported a timeout error
- Timed out during connection checkout
- Cannot specify maxAwaitTimeMS >= timeoutMS for a tailable aw
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/3da03eb7500056ec.json.
Report an issue: GitHub.