MongoDB Replica Set Election Failure? Here's the Fix

Database Errors Intermediate 👁 11 views 📅 Jun 14, 2026

A replica set election fails when members can't agree on a primary. The real fix is checking network latency and hidden votes.

Stuck with a Replica Set That Won't Pick a Primary?

You're staring at rs.status() and all you see is a list of SECONDARY nodes with no PRIMARY. I've been there. It's frustrating when your app goes read-only because MongoDB can't hold an election. Let's fix it. Skip the fluff — here's what actually works.

The Quick Fix: Check the Election Log and Network

Before you change anything, run rs.status() in your mongo shell. Look for the lastHeartbeatMessage field on each member. That field tells you what the member thinks is wrong. You'll often see something like: "Can't see the primary" or "Election failed: vote failed due to insufficient votes".

Here's the most common cause: one member has a slightly higher priority than the others, but it can't talk to the other members on port 27017 (or whatever you're using). The fix is simple — check network connectivity between all members. Use telnet or nc from each member to the others on your MongoDB port. If one member is isolated, that's your problem.

# From each member, test connectivity to the others
telnet member2.example.com 27017
telnet member3.example.com 27017

If you find a firewall rule blocking traffic, fix that. Then restart the mongod process on the isolated member. After that, run rs.reconfig() to force a re-election. Here's the command:

cfg = rs.conf()
cfg.members[0].priority = 1  # bump priority on the one you want as primary
rs.reconfig(cfg, {force: true})

After running rs.reconfig() with the force flag, you should see a new primary within a few seconds. Run rs.status() again — you'll see one member flip to PRIMARY.

Why This Fix Works

MongoDB's election algorithm is pretty straightforward. Every member sends heartbeats every 2 seconds. If a member can't reach the current primary (or if no primary exists), it triggers an election. The member with the highest priority that has a vote and can talk to a majority of voters wins.

The problem isn't usually the election logic — it's that one member can't see the others. That makes it unable to gather enough votes to become primary. By fixing network connectivity, you let the heartbeats flow again. The force: true option in rs.reconfig() overrides any stale configuration and forces a new election immediately.

I've seen this in AWS environments where security groups only allow inbound traffic from specific IP ranges, but the replica set members were in different subnets. Always double-check security group rules and VPC peering when you set up a replica set.

Less Common Variations of the Same Problem

Hidden Members and No Votes

Sometimes you have a hidden member (priority 0, hidden: true, votes: 1) that's supposed to be a backup but has a vote. If that hidden member goes down, you lose a vote. If your replica set has an even number of voting members, you can lose majority. For example, a 3-member replica set with all 3 voting — if one goes down, you still have 2 out of 3, which is a majority. But if you have 4 voting members (don't do that), losing one drops you to 3 out of 4, still a majority. But if you have 2 voting members (again, don't), losing one is 1 out of 2 — no majority. The fix: set votes: 0 on hidden or delayed members. That way they don't affect the election count.

cfg = rs.conf()
cfg.members[2].votes = 0  # set votes to 0 on the hidden member
rs.reconfig(cfg)

Priority 0 Members That Can't Be Primary

If you set a member's priority to 0, it can never become primary. That's by design. But I've seen people set priority 0 on all members except one, and then that one goes down. No one can be primary. The fix: make sure at least two members have a priority above 0. That way if one fails, the other can take over.

Stale Configuration from an Old Server

If you replaced a server and gave it the same hostname but a different IP, the replica set config might still have the old IP. Check rs.conf() — look at the host field for each member. If it's wrong, update it with rs.reconfig().

cfg = rs.conf()
cfg.members[0].host = "new-server.example.com:27017"
rs.reconfig(cfg)

Prevention: Set It Up Right from the Start

The best way to avoid election failures is to follow these rules when you create your replica set:

  • Use an odd number of voting members. 3 or 5 is standard. Avoid 2 or 4. If you must have an even number, set one member's votes to 0.
  • Set priority values thoughtfully. Give your primary a priority of 1 or 2, and secondaries a priority of 0.5 or 1. Never set all members to the same priority unless you want a free-for-all.
  • Check network latency. If your members are in different data centers, keep latency under 100ms. Higher latency causes missed heartbeats, which triggers unnecessary elections.
  • Monitor with Ops Manager or Cloud Manager. These tools alert you when a member goes down or an election occurs. That way you catch problems before they affect your app.

One last thing: if you're using MongoDB 5.0 or later, the election timeout changed from 10 seconds to 5 seconds. That means failed heartbeats trigger faster elections. Your network needs to be snappy. If you're on a slow link, consider increasing the electionTimeoutMillis setting in your replica set configuration, but don't go above 15 seconds — that makes failover too slow.

cfg.settings = {
  electionTimeoutMillis: 10000  # default is 5000 in 5.0+
}
rs.reconfig(cfg)

That's it. Check your network, check your votes, and check your hostnames. You'll have a primary in no time.

Was this solution helpful?