mongodb/node-mongodb-native · error · MongoServerError

This MongoDB deployment does not support retryable writes…

Error message

This MongoDB deployment does not support retryable writes. Please add retryWrites=false to your connection string.

What it means

Thrown as a MongoServerError when a write operation fails with the server error code IllegalOperation (the MMAPv1 retry-writes code) while retryWrites is enabled. The message instructs the user to disable retryWrites because the target deployment's storage engine (MMAPv1) or topology does not support retryable writes, which require WiredTiger and MongoDB 3.6+ replica set / 4.2+ sharded deployments. It is the user-facing rendering of MMAPv1_RETRY_WRITES_ERROR_MESSAGE.

Solutions

  1. Add retryWrites=false to your connection string (e.g. mongodb://host:27017/?retryWrites=false).
  2. Run MongoDB as a replica set (or sharded cluster) with the WiredTiger storage engine, which supports retryable writes.
  3. Upgrade MongoDB to 3.6+ (replica set) or 4.2+ (sharded) where retryable writes are supported.
  4. If using a managed service, confirm the deployment topology supports retryable writes.

Example fix

// before
const uri = 'mongodb://localhost:27017/?retryWrites=true';

// after
const uri = 'mongodb://localhost:27017/?retryWrites=false';
Defensive patterns

Strategy: validation

Validate before calling

import { MongoClient } from 'mongodb';

function buildUri(base: string) {
  const u = new URL(base);
  // For standalone / MMAPv1 deployments, retryable writes are unsupported
  if (u.searchParams.get('retryWrites') === 'true') {
    u.searchParams.set('retryWrites', 'false');
  }
  return u.toString();
}
const client = new MongoClient(buildUri('mongodb://localhost:27017/?retryWrites=true'));

Try / catch

try {
  await client.db().command({ ping: 1 });
} catch (err) {
  if (err instanceof MongoServerError && /retryWrites=false/.test(err.message)) {
    // add retryWrites=false to the URI and reconnect
  } else throw err;
}

Prevention

When it happens

Trigger: Connecting with retryWrites=true (the driver default for supported topologies) against a standalone server, an MMAPv1 storage engine deployment, or a pre-3.6 server, then performing any acknowledged single-document write (insertOne, updateOne, replaceOne, findOneAndUpdate, etc.). The first retryable write attempt returns code IllegalOperation and is rethrown at execute_operation.ts:289.

Common situations: Local development against a standalone mongod (no replica set); old MongoDB versions (<3.6); explicitly configuring retryWrites=true in the URI; running against a server that still uses the deprecated MMAPv1 storage engine.

Related errors


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

Appendix: source

Thrown at src/operations/execute_operation.ts:289

    } catch (operationError) {
      // Should never happen but if it does - propagate the error.
      if (!(operationError instanceof MongoError)) throw operationError;

      // Preserve the original error once a write has been performed.
      // Only update to the latest error if no writes were performed.
      if (error == null) {
        error = operationError;
      } else {
        if (!operationError.hasErrorLabel(MongoErrorLabel.NoWritesPerformed)) {
          error = operationError;
        }
      }

      // Reset timeouts
      timeoutContext.clear();

      if (hasWriteAspect && operationError.code === MMAPv1_RETRY_WRITES_ERROR_CODE) {
        throw new MongoServerError({
          message: MMAPv1_RETRY_WRITES_ERROR_MESSAGE,
          errmsg: MMAPv1_RETRY_WRITES_ERROR_MESSAGE,
          originalError: operationError
        });
      }

      if (!canRetry(operation, operationError)) {
        throw error;
      }

      if (operationError.hasErrorLabel(MongoErrorLabel.SystemOverloadedError)) {
        const maxOverloadAttempts = topology.s.options.maxAdaptiveRetries + 1;
        maxAttempts = Math.min(maxOverloadAttempts, operation.maxAttempts ?? maxOverloadAttempts);
      }

      if (attempt + 1 >= maxAttempts) {
        throw error;
      }

View on GitHub (pinned to dce7939f86)