mongodb/node-mongodb-native · error · MongoOperationTimeoutError

Server roundtrip time is greater than the time remaining

Error message

Server roundtrip time is greater than the time remaining

What it means

Thrown in sendWire (src/cmap/connection.ts:482-490) when Client-Side Operation Timeouts (CSOT) are enabled, a minRoundTripTime was configured, and the remaining time budget is smaller than that minimum round-trip estimate. The driver reasons that the request cannot possibly complete in time, so it fails fast with a MongoOperationTimeoutError before reading any response frames.

Source

Thrown at src/cmap/connection.ts:487

        agreedCompressor: this.description.compressor ?? 'none',
        zlibCompressionLevel: this.description.zlibCompressionLevel,
        timeoutContext: options.timeoutContext,
        signal: options.signal
      });

      if (message.moreToCome) {
        yield MongoDBResponse.empty;
        return;
      }

      this.throwIfAborted();

      if (
        options.timeoutContext?.csotEnabled() &&
        options.timeoutContext.minRoundTripTime != null &&
        options.timeoutContext.remainingTimeMS < options.timeoutContext.minRoundTripTime
      ) {
        throw new MongoOperationTimeoutError(
          'Server roundtrip time is greater than the time remaining'
        );
      }

      for await (const response of this.readMany(options)) {
        this.socket.setTimeout(0);
        const bson = response.parse();

        const document = (responseType ?? MongoDBResponse).make(bson);

        yield document;
        this.throwIfAborted();

        this.socket.setTimeout(timeout);
      }
    } finally {
      this.socket.setTimeout(0);
    }

View on GitHub (pinned to 3366c21a63)

Solutions

  1. Increase timeoutMS to comfortably exceed network round-trip time plus expected server work.
  2. Remove or lower minRoundTripTimeMS if you set it manually.
  3. Avoid sharing a single timeout context across many sequential operations; give each its own timeout.
  4. Profile actual RTT with a ping and set timeoutMS >= 2-4x RTT + query cost.

Example fix

// before
await coll.find({}, { timeoutMS: 5 }).toArray(); // too low for WAN

// after
await coll.find({}, { timeoutMS: 1000 }).toArray();
Defensive patterns

Strategy: validation

Validate before calling

function validateTimeoutVsRtt(timeoutMS: number, rttMS: number, minRtt?: number) {
  const floor = minRtt ?? rttMS;
  if (timeoutMS < floor * 2) {
    throw new Error(`timeoutMS (${timeoutMS}) must exceed ~2x RTT (${rttMS})`);
  }
}

Type guard

function timeoutExceedsRtt(timeoutMS: number | undefined, rttMS: number): boolean {
  return timeoutMS === undefined || timeoutMS > rttMS;
}

Try / catch

import { MongoOperationTimeoutError } from 'mongodb';
try {
  await collection.find({}, { timeoutMS: 10 }).toArray();
} catch (e) {
  if (e instanceof MongoOperationTimeoutError && /roundtrip/i.test(e.message)) {
    // raise timeoutMS and retry with backoff
  }
  throw e;
}

Prevention

When it happens

Trigger: Setting timeoutMS on an operation (or globally) plus a minRoundTripTimeMS such that remaining time < min round trip. Triggered by any operation whose per-op timeout budget has nearly expired when the read phase begins - common with very small timeoutMS values or cascaded operations sharing one timeout context.

Common situations: Setting timeoutMS to a value barely above network latency (e.g. 5ms over a WAN); nested operations under one timeout context where earlier stages consumed most of the budget; misconfigured minRoundTripTimeMS; slow network with aggressive timeouts.

Related errors


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