Unclean leader election
Availability chosen over durability, which silently discards acknowledged writes
replication.factor=3 min.insync.replicas=2 unclean.leader.election.enable=true
Paste replication.factor and min.insync.replicas from the broker or topic config, and acks from the producer config, and see exactly how many broker failures the combination survives: how many before writes are refused, and how many before a write you were told had succeeded is gone. The three settings are owned by different people, which is why the combination is wrong so often.
Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.
The answer appears here
Paste on the left and press Work out the tolerance. Nothing leaves this tab.
Nothing else to flag.
No formatting problems, and nothing the rules object to. Worth remembering what that covers: this reads the file you pasted, not the account or cluster it will be applied to.
No finding matches that filter.
Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.
Availability chosen over durability, which silently discards acknowledged writes
replication.factor=3 min.insync.replicas=2 unclean.leader.election.enable=true
Any single broker restart stops writes entirely
replication.factor=3 min.insync.replicas=3 acks=all
These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.
With RF=3 and min.isr=3, one broker restarting stops writes entirely. There is no headroom for routine maintenance.
Instead:min.isr = RF - 1. With RF=3 that is 2, which tolerates one broker down.
It allows an out-of-sync replica to become leader, which discards acknowledged writes to restore availability.
Instead:Leave it false unless availability genuinely outranks durability, and document the choice.
min.isr is only consulted for acks=all writes. With acks=1 it does nothing at all, which is why the setting appears not to work.
Instead:The two settings are a pair. Neither works alone.
The arithmetic is small. Being certain which of the two numbers you are looking at is the part that prevents both the outage and the data loss.
How many brokers can fail before writes are refused, and how many before a write you were told succeeded is gone. They are different numbers and they move in opposite directions: acks=1 keeps writing through more failures than acks=all, and loses data on the first one.
RF=3 with min.insync.replicas=3 tolerates zero failures. One broker restarting refuses every write to that topic with NotEnoughReplicasException, including during a routine rolling upgrade. It is reached by trying to be safer than RF=3 with min.insync.replicas=2, which is the setting that actually survives a failure.
min.insync.replicas is only enforced for acks=all and acks=-1. With acks=1 it is never consulted, so the broker config promises two copies and the producer takes one. This is the most common real data-loss configuration in Kafka, because both halves look correct to the person who owns them.
enable.idempotence became true by default in 3.0, and idempotence forces acks=all. An absent acks therefore means acks=all on a newer client and acks=1 on an older one. Rather than picking one, both readings are worked out and shown, because the file does not say which client you have.
Three settings decide whether a Kafka write survives, and they are owned by different people. replication.factor and min.insync.replicas belong to whoever runs the cluster. acks lives in application code. Neither party sees the other's value, and no single config file shows the problem.
With acks=all, a write is acknowledged only while at least min.insync.replicas replicas are in sync. So writes survive replication.factor minus min.insync.replicas failures, and an acknowledged write sits on min.insync.replicas replicas, which means it survives the permanent loss of one fewer than that.
RF=3 min.insync=2 acks=all
writes survive 1 failure, refused at 2
every acknowledged write is on 2 replicas
RF=3 min.insync=3 acks=all
writes survive 0 failures, refused at 1
one broker restarting stops the topic
RF=3 min.insync=4 acks=all
no write is ever accepted The broker only checks the in-sync count for acks=all and acks=-1. With acks=1 the leader answers as soon as the message is in its own log, before any follower has a copy, and a leader that dies in that window takes the message with it. The producer has already been told the write succeeded. Nothing logs an error, and the topic still describes itself as having three replicas.
producer: acks=1
broker: min.insync.replicas=2
what the platform team believes: 2 copies before ack
what actually happens: 1 copy, then ack
what is lost when the leader dies: everything not
yet replicated, silently With it on, Kafka may elect a replica that is behind when no in-sync replica is available. The new leader's log becomes the truth and everything the old leader had is discarded, so acknowledged messages disappear and consumers that had read past that offset see it rewind. Turning it off means a partition with no in-sync replica stays offline until one returns, which is the correct trade for anything you cannot lose.
Three replicas across two racks means one rack holds two of them, so losing that rack is two simultaneous failures rather than one, and the tolerance above no longer applies. Kafka only spreads replicas across racks when broker.rack is set on the brokers. Add racks=N to what you paste here and that arithmetic is done too.
RF=3, min.insync=2, spread over 2 racks
losing one rack removes 2 of the 3 replicas
1 replica left, below min.insync.replicas
writes refused, and a write committed on the
two replicas in that rack is gone Every number here assumes the ISR is full at replication.factor. A follower that exceeds replica.lag.time.max.ms leaves the ISR with no broker failing at all, which moves the whole table up by one. A topic-level override also beats the broker default, and neither the override nor the current ISR is in a properties file. kafka-topics --describe --under-min-isr-partitions names the partitions that are already refusing writes.