Ceph monitor election storm: monitors that cannot hold a stable quorum
A Ceph monitor election storm is what happens when the MON cluster cannot complete and hold an election. Each round of Paxos leader election starts, partially completes, then restarts before the new leader can commit any map updates. The election epoch counter climbs, the leader name changes moment to moment, and ceph -s itself starts taking several seconds to return because even reading the current map requires a responsive leader.
Client I/O often keeps working for a while. Existing clients hold cached OSD and CRUSH maps and continue pushing reads and writes to the OSDs they already know about. What is frozen is the control plane: no OSD up/down changes commit, no PG remaps are accepted, no pool changes take effect, no new client maps are handed out. As the storm persists, the gap between the frozen maps and reality widens until clients and OSDs begin to time out.
This page covers how to recognize the storm quickly, what the stable causes are, and how to break the loop without making the quorum loss worse. It assumes a 3-MON or 5-MON deployment on Reef (18.x) or Squid (19.x), though the mechanics are similar back through Pacific.
What this means
Ceph monitors form a Paxos quorum. A strict majority (floor(n/2) + 1 of the MON count) must agree on every cluster map update before it is committed. Elections exist to pick the single leader that runs Paxos rounds. Under normal conditions an election completes in seconds and the cluster never thinks about it again.
An election storm is a sustained failure to keep that leader. The classic signature, drawn from operator reports and the upstream MON code, is the lease timeout loop. The leader grants itself a lease, the peons (non-leader quorum members) must acknowledge that lease before it expires, and when they cannot reach the leader in time they call a new election. The new election hands the lease to another monitor, which also cannot hold it, and the cycle repeats faster than any single round can commit a map update.
flowchart TD
A[Leader elected] --> B[Leader grants Paxos lease]
B --> C{Peons ack lease in time?}
C -- yes --> D[Paxos round commits map update]
D --> A
C -- no, timeout --> E[Peon calls new election]
E --> F[New leader elected]
F --> G{Leader can keep lease?}
G -- clock skew / slow store / partition --> E
G -- yes --> BThe visible symptoms from the CLI:
ceph -stakes several seconds (sometimes 10 or more) because the tool is waiting on a MON that keeps cycling.ceph quorum_statusshows anelection_epochthat ticks upward across repeated samples.- The
quorum_leader_namefield changes between runs. ceph health detailshowsMON_CLOCK_SKEWor, in the worst case, never returns a clean health check.
During the storm, OSD map epoch updates stall. OSDs that fail heartbeats do not get marked down. New OSDs that join do not get marked up. PGs that need to re-peer cannot, because peering decisions require committed map updates. If an OSD is also failing at the same time, the cluster cannot respond to it, which compounds the problem.
Common causes
| Cause | What it looks like | First thing to check |
|---|---|---|
| Clock skew between MON hosts | MON_CLOCK_SKEW health check active, leader keeps rotating | ceph time-sync-status and chronyc tracking on each MON |
| MON-to-MON network partition | Subset of MONs cannot reach the leader, elections ping-pong across the partition | ping between every MON pair, switch and NIC error counters |
| One MON on slow storage | A single MON cannot keep Paxos pace, drags commit latency, peons time out | ceph daemon mon.<name> perf dump paxos section on each MON |
| MON store corruption | One MON logs RocksDB errors, refuses to join, destabilizes quorum | MON log for RocksDB errors, store size outlier |
| Overloaded co-located MON host | MON host CPU or I/O saturated by co-located OSDs, RGW, or VMs | top, iostat, vmstat on the MON host |
On recent Ceph releases, clock skew is the first suspect. The upstream troubleshooting guidance is explicit that there is no obvious reason other than clock skew that explains why an electing state would persist.
Quick checks
Run these read-only. None change cluster state.
# Time a basic status call. Several seconds indicates MON trouble.
time ceph -s
# Quorum state, election epoch, leader name. Run it twice, seconds apart,
# and compare election_epoch and quorum_leader_name.
ceph quorum_status -f json | jq '{epoch: .election_epoch, leader: .quorum_leader_name, quorum: .quorum_names}'
# Per-MON state and election_epoch from each daemon's own view.
ceph daemon mon.<name> mon_status
# Clock skew view from the lead monitor.
ceph time-sync-status
# Health detail, filtered for the clock skew check.
ceph health detail | grep -i clock
# Paxos and election counters on each MON.
ceph daemon mon.<name> perf dump | jq '{paxos: .paxos, mon: .mon}'
# MON store size on each MON host.
du -sh /var/lib/ceph/mon/ceph-$(hostname -s)/store.db
# NTP/chrony state on each MON host.
chronyc tracking # or: ntpq -p
If ceph quorum_status itself hangs, that confirms the MON cluster is not serving requests reliably. Sample election_epoch a few times. In a healthy cluster it barely moves. In a storm it climbs across every sample.
How to diagnose it
Confirm it is actually a storm. Sample
ceph quorum_statusthree times, 5 seconds apart. Ifelection_epochincreases between every sample andquorum_leader_namechanges, you have a storm, not a one-off election.Check clock sync first. Run
ceph time-sync-statusandchronyc tracking(orntpq -p) on every MON host. The defaultmon_clock_drift_allowedis 0.05 seconds. Anything beyond that triggersMON_CLOCK_SKEWand is enough to destabilize elections. VM-hosted MONs are particularly prone to this.Check MON-to-MON network reachability. From each MON host, ping every other MON host. Look for packet loss, not just latency. A partial partition where two MONs can reach each other but not the third produces exactly the ping-pong leader pattern of an election storm. Check switch error counters and NIC drop counters on the MON hosts.
Find the slow MON. On each MON, run
ceph daemon mon.<name> perf dumpand look at thepaxos.commit_latencyandpaxos.accept_latencyvalues. One outlier with commit latency in the hundreds of milliseconds (or worse) is the one that cannot keep Paxos pace. In a 3-MON cluster the leader needs only one peon ack to commit, but a slow peon will fail to ack its Paxos lease in time and trigger a new election. One slow MON destabilizes the whole quorum.Check the MON store on each host. A bloated or corrupt store slows every Paxos round. Compare
du -sh /var/lib/ceph/mon/ceph-<name>/store.dbacross MONs. A store that is an order of magnitude larger than the others, or that shows RocksDB errors in the MON log, is a candidate for removal and rebuild.Check MON host resource pressure. Run
top,iostat -xz 1, andfree -mon each MON host. A MON co-located with busy OSDs, RGW, or other VMs can be starved of CPU or disk I/O at the exact moment it needs to respond to a Paxos round.
Metrics and signals to monitor
| Signal | Why it matters | Warning sign |
|---|---|---|
ceph_mon_quorum_status (per MON) | Tells you who is in quorum right now | Any MON flipping between 1 and 0, or a sustained 0 on any member |
MON_CLOCK_SKEW health check | The single most common storm trigger | Active for more than 60 seconds |
Paxos commit_latency (per MON, via perf dump) | Measures whether the leader can actually commit rounds | One MON with latency 5-10x the others |
election_epoch from quorum_status | Direct measure of election churn | Incrementing more than once per minute |
election_call, election_win, election_lose (per MON) | Shows who is calling and losing elections | election_call count climbing rapidly on a non-leader |
| MON store size (host filesystem) | Large stores slow startup and elections | Store over 10 GB, or one MON much larger than others |
| MON host CPU and I/O | A starved MON cannot answer Paxos rounds in time | Sustained high iowait or CPU on the MON host |
| NTP/chrony offset (host metrics) | Underlying cause of clock skew | Offset trending away from zero between corrections |
The Netdata Ceph collector surfaces ceph_mon_quorum_status and ceph_health_detail signals directly. The host-level NTP offset, CPU, and disk I/O on each MON host come from the standard Netdata system collectors. Correlating cluster-side signals with host-side signals tells you whether the storm is a Ceph problem or a host problem.
Fixes
Clock skew
Fix the underlying time sync. Do not raise mon_clock_drift_allowed to make the warning go away. Upstream is explicit that this masks the problem and the cluster will still misbehave, just without telling you.
- Verify
chronyd(orntpd) is running on every MON host:systemctl status chronyd. - Verify each MON can reach its time source:
chronyc sources. - If MONs are VMs, verify the hypervisor is not stealing time. VM-virtualized clocks are explicitly called out as unsuitable for steady timekeeping on monitor nodes. Prefer bare metal for MON hosts, or at minimum ensure the hypervisor is not oversubscribed.
- Once clocks are within 50ms of each other and stable, elections should settle within a minute or two.
MON-to-MON network partition
A partition that splits the MONs into two groups that cannot reach each other produces unstable elections. The fix is network-level: find the bad link, switch port, or NIC and repair it. Do not try to tune Ceph around a broken network.
If the partition is asymmetric and one MON is isolated, you can stop that MON’s daemon to let the remaining MONs form a stable quorum. In a 3-MON cluster this leaves you with 2 MONs and zero fault tolerance, so treat it as a stopgap while you repair the network, not a permanent state.
One MON on slow storage
A MON whose store sits on spinning rust, or whose DB device is shared and saturated, cannot keep up with Paxos rounds. The symptom is one MON with paxos.commit_latency far higher than its peers.
- Move the MON store to SSD-backed storage. The path is
/var/lib/ceph/mon/ceph-<name>/store.db. - If the store has bloated, trigger a manual compaction with
ceph daemon mon.<name> compact. This causes a brief latency spike during compaction, so run it during a maintenance window if possible. - If compaction does not help and the store is corrupt, rebuild the MON from a healthy peer.
MON store corruption
If a MON is logging RocksDB errors or refusing to join quorum, it may have a corrupt store. The safe recovery path is to remove that MON from the quorum, wipe its store, and let it rejoin from a healthy peer.
As a general pattern: stop the daemon, remove the MON from the MON map if needed, wipe the data directory, and redeploy the MON so it bootstraps from an existing quorum member. This is disruptive to that one MON but does not risk the quorum as long as the other MONs are healthy.
In extreme cases where all MONs are stuck in electing state and no quorum can form, operators have recovered by reducing to a single MON (removing all others from the MON map) so the survivor boots without waiting for quorum, then re-adding the others. This is a last resort with real risk: a single MON has no redundancy. Do it only when the alternative is a permanently frozen cluster, and re-add the second and third MONs immediately.
Overloaded co-located MON host
A MON that shares a host with busy OSDs, RGW instances, or other workloads can be starved at the wrong moment. The clean fix is to give MONs dedicated hosts, or at minimum dedicated CPU and disk resources. If that is not possible in the short term, reduce the load on the co-located services during the storm: throttle recovery, pause scrubs, or move workloads off the MON host.
Prevention
- Run MONs on dedicated, bare-metal hosts. Co-location with OSDs or RGW is the most common preventable cause of MON starvation. VMs are workable but riskier.
- Put the MON store on SSD. Spinning rust is not fast enough for reliable Paxos rounds on a busy cluster.
- Monitor NTP offset on every MON host continuously. Catch drift before it crosses the 50ms threshold.
- Monitor
election_epochrate. A healthy cluster barely increments it. More than a handful of elections per hour warrants investigation. - Monitor MON store size and Paxos commit latency per MON. Outliers are the ones that will eventually destabilize quorum.
- Keep the MON network simple and redundant. Avoid asymmetric routing or flaky links between MON hosts. The classic election algorithm is known to misbehave under netsplit conditions.
On Reef and later, the connectivity election strategy (ceph mon set election_strategy) is available as an alternative to the classic lowest-rank algorithm and is designed to handle netsplit conditions better. It remains opt-in. If you operate a stretch cluster or one with historically flaky MON networking, evaluate it in a test environment before relying on it in production.
How Netdata helps
ceph_mon_quorum_statusper MON shows immediately which monitors are in and out of quorum, and whether membership is flapping. A graph that toggles every few seconds is the visual fingerprint of a storm.ceph_health_detail{name="MON_CLOCK_SKEW"}surfaces the most common root cause directly, with per-second resolution so you can see when skew started and whether your NTP fix took hold.- Host-level CPU, I/O, and memory collectors on each MON host let you correlate a storm with co-located workload pressure. If commit latency spikes line up with OSD disk utilization spikes on the same host, you have your cause.
- Anomaly detection on
election_epochrate and per-MON quorum membership flags an emerging storm before operators notice thatceph -sis slow.
Related guides
- Ceph monitor quorum lost: the cluster can no longer update its maps
- Ceph health detail: mapping ceph_health_detail checks to a cause
- Ceph HEALTH_ERR: reading the umbrella status and finding the real fault
- Ceph HEALTH_WARN: which warnings are noise and which are structural
- How Ceph actually works in production: a mental model for operators
- Ceph monitoring checklist: the signals every production cluster needs
- Ceph monitoring maturity model: from survival to expert
- Ceph OSD flapping: OSDs cycling up and down and the peering storm that follows
- Ceph OSD down: telling a dead disk apart from a network blip






