mongodb/node-mongodb-native · error · MongoTransactionError

Read preference in a transaction must be primary, not

Error message

Read preference in a transaction must be primary, not: ${readPreference.mode}

What it means

Thrown when an operation inside an active transaction uses a read preference other than primary. MongoDB transactions must read from the primary (except when the transaction has been pinned to a mongos after a sharded operation, which the driver handles internally), so the driver rejects secondary/nearest/secondaryPreferred before sending the command.

Solutions

  1. Inside withTransaction, let the driver use primary by default — do not override readPreference on individual operations.
  2. If you set readPreference at the client or collection level, override it to 'primary' for operations within the transaction.
  3. For read-only workloads that don't need transactional multi-document atomicity, consider running outside a transaction with the secondary read preference.

Example fix

// before
await session.withTransaction(async () => {
  await collection.find({}, { session, readPreference: 'secondary' }).next();
});

// after
await session.withTransaction(async () => {
  await collection.find({}, { session }).next(); // primary by default
});
Defensive patterns

Strategy: validation

Validate before calling

if (session?.inTransaction() && readPreference && readPreference !== 'primary') {
  throw new Error('Read preference inside a transaction must be primary');
}

Prevention

When it happens

Trigger: Calling collection.find({}, { session, readPreference: 'secondary' }) while session.inTransaction() is true. Also from setting a non-primary read preference on the collection or client and then running operations inside a transaction.

Common situations: Read-heavy analytics that default to secondary reads but accidentally run inside a withTransaction block; read preference inherited from the URI (&readPreference=secondary) conflicting with transactional writes.

Related errors


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

Appendix: source

Thrown at src/operations/execute_operation.ts:110

  ) {
    throw new MongoCompatibilityError('Snapshot reads require MongoDB 5.0 or later');
  } else if (session.client !== client) {
    throw new MongoInvalidArgumentError('ClientSession must be from the same MongoClient');
  }

  operation.session ??= session;

  const readPreference = operation.readPreference ?? ReadPreference.primary;
  const inTransaction = !!session?.inTransaction();

  const hasReadAspect = operation.hasAspect(Aspect.READ_OPERATION);

  if (
    inTransaction &&
    !readPreference.equals(ReadPreference.primary) &&
    (hasReadAspect || operation.commandName === 'runCommand')
  ) {
    throw new MongoTransactionError(
      `Read preference in a transaction must be primary, not: ${readPreference.mode}`
    );
  }

  if (session?.isPinned && session.transaction.isCommitted && !operation.bypassPinningCheck) {
    session.unpin();
  }

  timeoutContext ??= TimeoutContext.create({
    session,
    serverSelectionTimeoutMS: client.s.options.serverSelectionTimeoutMS,
    waitQueueTimeoutMS: client.s.options.waitQueueTimeoutMS,
    timeoutMS: operation.options.timeoutMS
  });

  try {
    return await executeOperationWithRetries(operation, {
      topology,

View on GitHub (pinned to dce7939f86)