- Error code
- 10107
- Code name
NotWritablePrimary- Product
- MongoDB
- Versions
- MongoDB 7.0 and 8.0 (wordings checked against the 8.0 source; older servers and clients say "not master")
- Category
- Replication & Connectivity
- Last reviewed
- 24 October 2026
On this page
What it means
Error 10107 (NotWritablePrimary) means a write, or a command that must run on the primary, reached a replica set member that is not the primary. Its sibling 13435 (NotPrimaryNoSecondaryOk) means a read reached a secondary without a read preference allowing it.
In a replica set only the primary accepts writes. When a write or another primary-only command arrives at a secondary, or at a former primary that has just stepped down, the member rejects it at command dispatch with not primary. Reads are different: a secondary serves a read only when the request says secondaries are acceptable (a read preference other than primary). Without that, the member answers not primary and secondaryOk=false, code 13435. Servers send the old not master and slaveOk wording only to clients that do not announce support for the hello command.
MongoDB's error_codes.yml puts both codes in the NotPrimaryError and RetriableError categories. Drivers use this: with retryable writes (on by default in current drivers and in mongosh) a write that fails this way is retried once, after the driver has waited up to serverSelectionTimeoutMS for a new primary. The documentation says the median time to elect a new primary should not typically exceed 12 seconds with default settings, so a short burst of these errors during failover or maintenance is normal; a steady stream is not.
Why direct connections matter
A connection string that lists the replica set lets the driver discover the members and send writes to whichever is primary. A direct connection to one member (directConnection=true) sends everything to that member, so writes fail with 10107 whenever it is a secondary. For reads, the driver server selection specification says a client in a direct connection must send primaryPreferred when the application asked for primary, so current drivers and mongosh normally avoid 13435 even on a secondary; it now mostly comes from older shells and drivers, or tools that build their own requests.
Common causes
- The client is connected directly to one member (directConnection=true, or an old client given a single host) that is, or has become, a secondary.
- A primary election or step-down, including planned maintenance, while writes are in flight.
- Retryable writes are disabled (retryWrites=false), so a write during failover is not retried.
- A read from a secondary by an older client or tool that does not set a secondary-friendly read preference (13435).
- A multi-document transaction or an admin command such as createIndexes started on a member that is not primary.
Diagnose it
Read-only These mongosh commands only read data, indexes, statistics and server state (find, aggregate without $out or $merge, getIndexes, stats, currentOp, rs.status). They do not change data, users or settings, so they are safe to run first.
What is this member, and who is primary?
const h = db.hello()
({ me: h.me, isWritablePrimary: h.isWritablePrimary, secondary: h.secondary, primary: h.primary, setName: h.setName }) isWritablePrimary: false and secondary: true mean you are on a secondary; primary names the current primary, if there is one.
Member states and recent elections
rs.status().members.map(m => ({ name: m.name, state: m.stateStr, health: m.health, uptime: m.uptime })) Each member's state. Exactly one should be PRIMARY. Short uptimes or no PRIMARY at all point to an election or members that keep restarting.
How is the application connected?
Read the connection string in the application's configuration (not the one you typed into mongosh). Look for directConnection=true, a single host without replicaSet, retryWrites=false, or no readPreference when you intend to read from secondaries.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Connect to the replica set, not to one member
Client or network sideList the members (or use the mongodb+srv address) and name the set, so the driver tracks which member is primary and sends writes there.
mongodb://m1.example.net:27017,m2.example.net:27017,m3.example.net:27017/shop?replicaSet=rs0
Keep retryable writes on and handle failover
Client or network sideLeave retryWrites at its default (true). For writes that are still failing after the single retry, retry with a short back-off in application code, treating codes in the NotPrimaryError category as transient.
mongodb://m1.example.net:27017,m2.example.net:27017,m3.example.net:27017/shop?replicaSet=rs0&retryWrites=true
Allow reads from secondaries explicitly (13435)
Client or network sideWhen reading from secondaries is intended, set a read preference such as secondaryPreferred in the connection string, or for the session in mongosh. Secondary reads can return slightly older data.
db.getMongo().setReadPref("secondaryPreferred")
db.orders.find({ status: "open" })
Run admin and index commands on the primary
Client or network sideConnect to the set (not a member) for createIndexes, collection changes and transactions, or connect to the member that db.hello().primary names.
Examples
Writing through a direct connection to a secondary
Not reproduced here: no MongoDB server is installed for this site. The text is the one set in MongoDB 8.0's service_entry_point_common.cpp for a client that supports hello, as mongosh does; the host names are illustrative.
// mongosh "mongodb://m2.example.net:27017/shop?directConnection=true" (m2 is a secondary)
db.orders.insertOne({ item: "pen", qty: 5 })
MongoServerError: not primary
Reading from a secondary with an older client (13435)
Not reproduced here: no MongoDB server is installed for this site. The fields are those of a server error reply; the "not master and slaveOk=false" wording is what MongoDB 8.0 sends to clients that do not support hello, and current clients get "not primary and secondaryOk=false". How the legacy shell prints the reply is illustrative.
// legacy mongo shell connected to m2.example.net, a secondary, without secondaryOk
db.orders.find()
{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotPrimaryNoSecondaryOk" }
How to prevent it
Always connect applications to the replica set with all members (or the SRV address) and the set name, keep retryable writes and retryable reads on, and reserve directConnection for administration of one member.
Handle the NotPrimaryError category as transient in code, log the codeName, and alert when these errors continue for longer than a normal election.
Common questions
What does "not primary" mean in MongoDB?
The member that received a write is not the replica set primary, either because you are connected directly to a secondary or because an election just happened. Connect to the replica set so the driver finds the primary.
How do I fix "not primary and secondaryOk=false"?
Set a read preference that allows secondaries, such as secondaryPreferred, or connect to the replica set so primary reads go to the primary. Older shells needed secondaryOk to be enabled for the session.
Is NotWritablePrimary safe to retry?
Yes: MongoDB classes it as a retriable error, and retryable writes retry it once automatically after a new primary is found.
Learn more on CodeWithSQL
Official documentation
Last technically reviewed 24 October 2026; examples and diagnostics run on MongoDB 8.0 documentation and source (error_codes.yml r8.0.0); not run locally. Codes and code names are checked against MongoDB's error_codes.yml (8.0); no MongoDB server was available, so the examples were not run locally.