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
- Inside withTransaction, let the driver use primary by default — do not override readPreference on individual operations.
- If you set readPreference at the client or collection level, override it to 'primary' for operations within the transaction.
- 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
- Do not set readPreference on operations inside withTransaction.
- Audit collection/client-level readPreference defaults before entering a transaction.
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
- Argument "docs" must be an array of documents
- Argument "operations" must be an array of documents
- Argument "pipeline" must be an array of aggregation stages
- Cannot call abortTransaction after calling commitTransaction
- Cannot call abortTransaction twice
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)