mongodb/node-mongodb-native · error · MongoOperationTimeoutError
Server reported a timeout error
Error message
Server reported a timeout error
What it means
A MongoOperationTimeoutError thrown inside Connection.sendCommand when the server returns a document with ok === 0, CSOT is enabled, and the response is identified as a maxTimeMS-expired error. The original server error is wrapped as the cause so callers can inspect both the CSOT framing and the underlying MongoServerError.
Solutions
- Increase timeoutMS for the operation or the client.
- Optimize the query: add indexes, use $limit, or restructure the aggregation pipeline.
- Check server load and slow-query logs; the cause field carries the server's error details.
- Use operation-level timeoutMS only where needed rather than a tiny global timeout.
Example fix
// before
await coll.find({}).maxTimeMS(100).toArray(); // server-enforced, may 122 under CSOT
// after
await coll.find({}, { timeoutMS: 30000 }).toArray(); Defensive patterns
Strategy: try-catch
Type guard
function isCSOTTimeout(e: unknown): e is MongoOperationTimeoutError {
return e instanceof MongoOperationTimeoutError && /Server reported a timeout/.test(e.message);
} Try / catch
try {
await cursor.toArray();
} catch (e) {
if (e instanceof MongoOperationTimeoutError) {
// increase timeoutMS or optimize query, then retry
} else throw e;
} Prevention
- Set timeoutMS comfortably above expected query duration.
- Add indexes to keep queries within budget.
- Use $limit and early $project in aggregations.
When it happens
Trigger: An operation runs under CSOT (timeoutMS set), the server receives maxTimeMS (derived from the remaining budget) and the query exceeds it server-side, returning a MaxTimeMSExpired-style error. The driver converts this into a MongoOperationTimeoutError to present a uniform timeout surface.
Common situations: Long-running aggregations or finds with a small timeoutMS; server under load causing queries to exceed the derived maxTimeMS; using timeoutMS where legacy socketTimeoutMS was previously used with more headroom.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- An operation cannot be given a timeoutMS setting when…
- Cannot set timeoutMode without setting timeoutMS
- Cannot specify maxAwaitTimeMS >= timeoutMS for a tailable…
- Cannot use maxTimeMS with timeoutMS for explain commands.
- Expired after ms
AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11).
Data as JSON: /api/errors/d4d3410387a0961f.
Report an issue: GitHub.
Appendix: source
Thrown at src/cmap/connection.ts:559
let document: MongoDBResponse | undefined = undefined;
/** Cached result of a toObject call */
let object: Document | undefined = undefined;
try {
this.throwIfAborted();
for await (document of this.sendWire(message, options, responseType)) {
object = undefined;
if (options.session != null) {
updateSessionFromResponse(options.session, document);
}
if (document.$clusterTime) {
this.clusterTime = document.$clusterTime;
this.emit(Connection.CLUSTER_TIME_RECEIVED, document.$clusterTime);
}
if (document.ok === 0) {
if (options.timeoutContext?.csotEnabled() && document.isMaxTimeExpiredError) {
throw new MongoOperationTimeoutError('Server reported a timeout error', {
cause: new MongoServerError((object ??= document.toObject(bsonOptions)))
});
}
throw new MongoServerError((object ??= document.toObject(bsonOptions)));
}
if (this.shouldEmitAndLogCommand) {
this.emitAndLogCommand(
this.monitorCommands,
Connection.COMMAND_SUCCEEDED,
message.databaseName,
this.established,
new CommandSucceededEvent(
this,
message,
message.moreToCome ? { ok: 1 } : (object ??= document.toObject(bsonOptions)),
started,
this.description.serverConnectionIdView on GitHub (pinned to dce7939f86)