This error occurs when attempting to perform read operations on a MongoDB secondary replica set member without proper read preference configuration. By default, MongoDB restricts read operations to the primary node to ensure strict consistency.
The "NotPrimaryNoSecondaryOk" error indicates that a read operation was attempted on a secondary member of a MongoDB replica set, but the connection or query was not configured to allow reading from secondaries. MongoDB uses the `secondaryOk` flag (or read preference settings in modern drivers) to control whether reads can be executed on non-primary nodes. By default, MongoDB directs all read operations to the primary member to ensure strict consistency, as the primary reflects the latest writes. Secondary members replicate data asynchronously from the primary, which means they may have slightly stale data. To read from secondaries, you must explicitly configure your connection or query to allow it. This error commonly occurs when connecting directly to a secondary node without setting the appropriate read preference, or when the replica set topology changes (such as during a failover) and the node you're connected to is no longer primary.
First, check which node you're connected to and whether it's currently primary or secondary:
// In mongosh
rs.status()
rs.isMaster()Look for the stateStr field in the output. If it shows "SECONDARY", you're connected to a secondary node and need to configure read preferences.
The recommended approach is to set the read preference in your MongoDB connection string:
// Node.js with MongoDB driver
const uri = "mongodb://host1:27017,host2:27017,host3:27017/mydb?replicaSet=myReplicaSet&readPreference=secondaryPreferred";
const client = new MongoClient(uri);Read preference options:
- primary - Read only from primary (default)
- primaryPreferred - Read from primary, fall back to secondary if unavailable
- secondary - Read only from secondary members
- secondaryPreferred - Read from secondary, fall back to primary if none available
- nearest - Read from member with lowest network latency
You can also configure read preference programmatically in your application code:
// Node.js MongoDB driver
const { MongoClient, ReadPreference } = require('mongodb');
const client = new MongoClient(uri);
await client.connect();
const db = client.db('myDatabase');
const collection = db.collection('myCollection', {
readPreference: ReadPreference.SECONDARY_PREFERRED
});
// Or set at query level
const results = await collection.find({}).readPref('secondaryPreferred').toArray();# Python PyMongo
from pymongo import MongoClient, ReadPreference
client = MongoClient('mongodb://localhost:27017/', replicaSet='myReplicaSet')
db = client.get_database('myDatabase', read_preference=ReadPreference.SECONDARY_PREFERRED)
collection = db.myCollectionIf you're connecting directly to a secondary node using mongosh or the legacy mongo shell:
// In mongosh (MongoDB 5.0+)
db.getMongo().setReadPref('secondaryPreferred')
// Or for legacy mongo shell
rs.slaveOk() // Deprecated but still worksAfter running this command, you'll be able to execute read queries on the secondary node.
If you're connecting to a single host, switch to a replica set-aware connection string:
Instead of:
mongodb://secondary-host:27017/mydbUse:
mongodb://primary-host:27017,secondary1:27017,secondary2:27017/mydb?replicaSet=myReplicaSet&readPreference=secondaryPreferredThis allows the driver to:
- Automatically discover all replica set members
- Handle failovers gracefully
- Route reads according to your preference
- Reconnect to the new primary if the topology changes
If the error persists due to replica set misconfiguration (wrong IP addresses):
// Connect to the primary
mongosh "mongodb://primary-host:27017"
// Check current configuration
rs.conf()
// If IPs are incorrect, reconfigure
cfg = rs.conf()
cfg.members[0].host = "correct-ip-1:27017"
cfg.members[1].host = "correct-ip-2:27017"
cfg.members[2].host = "correct-ip-3:27017"
rs.reconfig(cfg)For Docker environments, ensure the replica set configuration uses hostnames or IPs that are accessible from your application.
Read Consistency Trade-offs:
When reading from secondaries, be aware that you may see stale data due to replication lag. Secondary members replicate asynchronously from the primary, typically with a lag of milliseconds to seconds depending on write load and network conditions. For applications requiring strong consistency, always use readPreference=primary.
Read Concern and Causal Consistency:
For applications that need to read their own writes from secondaries, use causal consistency sessions (MongoDB 3.6+):
const session = client.startSession({ causalConsistency: true });
await collection.insertOne({ ... }, { session });
const doc = await collection.findOne({ ... }, { session, readPreference: 'secondary' });
await session.endSession();Tag Sets for Geographically Distributed Replica Sets:
You can configure read preferences to target specific replica set members using tags:
const readPreference = {
mode: 'secondary',
tags: [{ datacenter: 'east' }, { datacenter: 'west' }]
};Hedged Reads (MongoDB 4.4+):
Enable hedged reads to send queries to multiple replica set members simultaneously and use the first response, reducing tail latency:
mongodb://host1:27017,host2:27017/?readPreference=nearest&hedged=trueLegacy Terminology:
Older MongoDB documentation and APIs may refer to slaveOk instead of secondaryOk. These terms are functionally equivalent, but modern drivers use "secondary" terminology. The rs.slaveOk() method is deprecated but still functional for backward compatibility.
StaleShardVersion: shard version mismatch
How to fix "StaleShardVersion: shard version mismatch" in MongoDB
MongoOperationTimeoutError: Operation timed out
How to fix "MongoOperationTimeoutError: Operation timed out" in MongoDB
MongoServerError: PlanExecutor error during aggregation :: caused by :: Sort exceeded memory limit of 104857600 bytes, but did not opt in to external sorting. Aborting operation.
How to fix "QueryExceededMemoryLimitNoDiskUseAllowed" in MongoDB
MissingSchemaError: Schema hasn't been registered for model
How to fix "MissingSchemaError: Schema hasn't been registered for model" in MongoDB/Mongoose
CastError: Cast to ObjectId failed for value "abc123" at path "_id"
How to fix "CastError: Cast to ObjectId failed" in MongoDB