mongodb/node-mongodb-native · error · MongoInvalidArgumentError

Option "maxStalenessSeconds" must be at least

Error message

Option "maxStalenessSeconds" must be at least ${SMALLEST_MAX_STALENESS_SECONDS} seconds

What it means

Thrown by maxStalenessReducer() (src/sdam/server_selection.ts:138) as MongoInvalidArgumentError when maxStalenessSeconds is below the absolute minimum SMALLEST_MAX_STALENESS_SECONDS (constant = 90, defined at server_selection.ts:9). This is the cross-driver spec floor: regardless of topology, maxStalenessSeconds must be >= 90.

Solutions

  1. Set maxStalenessSeconds to at least 90.
  2. If 90s is too stale for your use case, reconsider whether staleness-based selection is the right mechanism.

Example fix

// before
new ReadPreference('secondary', undefined, { maxStalenessSeconds: 60 });
// after
new ReadPreference('secondary', undefined, { maxStalenessSeconds: 90 });
Defensive patterns

Strategy: validation

Validate before calling

const MIN = 90;
function safeMaxStaleness(v) {
  if (v < MIN) throw new Error(`maxStalenessSeconds must be >= ${MIN}`);
  return v;
}

Type guard

function isAtLeast90(v): v is number {
  return typeof v === 'number' && v >= 90;
}

Try / catch

try {
  await collection.findOne({}, { readPreference: new ReadPreference('secondary', undefined, { maxStalenessSeconds }) });
} catch (e) {
  if (e instanceof MongoInvalidArgumentError && /at least 90/.test(e.message)) {
    // set to 90 and retry
  }
  throw e;
}

Prevention

When it happens

Trigger: Setting maxStalenessSeconds to any value from 1 to 89 (the variance check at line 131 may already have rejected smaller values depending on heartbeat).

Common situations: Setting low staleness values based on application latency targets without knowing the 90-second spec minimum.

Related errors


AI-assisted analysis of mongodb/node-mongodb-native@dce7939f86 (2026-08-11). Data as JSON: /api/errors/9b4c51da35b61af0. Report an issue: GitHub.

Appendix: source

Thrown at src/sdam/server_selection.ts:138

  readPreference: ReadPreference,
  topologyDescription: TopologyDescription,
  servers: ServerDescription[]
): ServerDescription[] {
  if (readPreference.maxStalenessSeconds == null || readPreference.maxStalenessSeconds < 0) {
    return servers;
  }

  const maxStaleness = readPreference.maxStalenessSeconds;
  const maxStalenessVariance =
    (topologyDescription.heartbeatFrequencyMS + IDLE_WRITE_PERIOD) / 1000;
  if (maxStaleness < maxStalenessVariance) {
    throw new MongoInvalidArgumentError(
      `Option "maxStalenessSeconds" must be at least ${maxStalenessVariance} seconds`
    );
  }

  if (maxStaleness < SMALLEST_MAX_STALENESS_SECONDS) {
    throw new MongoInvalidArgumentError(
      `Option "maxStalenessSeconds" must be at least ${SMALLEST_MAX_STALENESS_SECONDS} seconds`
    );
  }

  if (topologyDescription.type === TopologyType.ReplicaSetWithPrimary) {
    const primary: ServerDescription = Array.from(topologyDescription.servers.values()).filter(
      primaryFilter
    )[0];

    return servers.filter((server: ServerDescription) => {
      const stalenessMS =
        server.lastUpdateTime -
        server.lastWriteDate -
        (primary.lastUpdateTime - primary.lastWriteDate) +
        topologyDescription.heartbeatFrequencyMS;

      const staleness = stalenessMS / 1000;
      const maxStalenessSeconds = readPreference.maxStalenessSeconds ?? 0;

View on GitHub (pinned to dce7939f86)