mongodb/node-mongodb-native · error · MongoOperationTimeoutError
Server reported a timeout error
Error message
Server reported a timeout error
What it means
Thrown in sendCommand (src/cmap/connection.ts:557-562) when the server returned ok === 0, the response is flagged as a maxTime-expired error, and CSOT (timeoutMS) is enabled. The driver wraps the underlying MongoServerError as the cause of a MongoOperationTimeoutError so callers see a timeout-semantic error while preserving server diagnostics.
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 3366c21a63)
Solutions
- Increase timeoutMS for the specific operation or remove it to use the server default.
- Add indexes or optimize the query/aggregation pipeline to run within the budget.
- Use $maxTimeMS in the pipeline or cursor.maxTimeMS() to make the limit explicit and tunable.
- Offload long-running analytics to a dedicated read node with a larger budget.
Example fix
// before
await coll.aggregate(bigPipeline, { timeoutMS: 100 }).toArray();
// after
await coll.createIndexes([{ key: { field: 1 } }]);
await coll.aggregate(bigPipeline, { timeoutMS: 5000 }).toArray(); Defensive patterns
Strategy: retry
Validate before calling
function budgetForQuery(timeoutMS: number, estimatedWorkMS: number) {
if (timeoutMS < estimatedWorkMS) {
throw new Error(`timeoutMS ${timeoutMS} < estimated server work ${estimatedWorkMS}ms`);
}
} Type guard
import { MongoOperationTimeoutError } from 'mongodb';
function isServerMaxTimeExpired(e: unknown): e is MongoOperationTimeoutError {
return e instanceof MongoOperationTimeoutError &&
/Server reported a timeout/.test(e.message);
} Try / catch
import { MongoOperationTimeoutError } from 'mongodb';
async function findWithBackoff(coll: any, q: any, timeoutMS = 1000) {
for (;;) {
try { return await coll.find(q, { timeoutMS }).toArray(); }
catch (e) {
if (e instanceof MongoOperationTimeoutError && timeoutMS < 10000) {
timeoutMS *= 2; continue;
}
throw e;
}
}
} Prevention
- Add indexes for query shapes that hit maxTimeMS limits.
- Set timeoutMS per operation based on expected workload, not globally tiny.
- Use explain() to confirm the query is using an index before tightening timeouts.
When it happens
Trigger: Any command (query, aggregate, write) where the server's own maxTimeMS or the driver-translated timeoutMS elapsed server-side and the server replied with a maxTimeMSExpired error code. Common with large aggregations, unindexed queries, or long-running writes under a tight timeoutMS.
Common situations: Setting timeoutMS on an aggregation over a large collection without supporting indexes; cursor.getMore() exceeding the budget; write operations with wtimeout/journal concerns compounded by timeoutMS; slow queries against a loaded server.
Related errors
- KMS request timed out
- Server roundtrip time is greater than the time remaining
- Timed out during connection checkout
- Cannot specify maxAwaitTimeMS >= timeoutMS for a tailable aw
- Cannot set tailable cursor's timeoutMode to LIFETIME
AI-assisted analysis of mongodb/node-mongodb-native@3366c21a63 (2026-08-04).
Data as JSON: /data/errors/d4d3410387a0961f.json.
Report an issue: GitHub.