




Why does Kafka allow writes when ISR < min.insync.replicas (with acks=all)?
I’m currently learning Kafka, and while learning about ISR (In-Sync Replicas), acks, and min.insync.replicas, I tried to demonstrate the behavior in a local multi-broker setup.
I observed something that doesn’t match my understanding, so I wanted to ask here.
Setup
3 Kafka brokers running in Docker
Topic config:
- partitions = 3
- replication.factor = 3
- min.insync.replicas = 100
Topic description:
./kafka-topics.sh --describe --topic isr-error --bootstrap-server kafka-broker-one:9092
Output:
Topic: isr-error PartitionCount: 3 ReplicationFactor: 3 Configs: min.insync.replicas=100
Partition: 0 Leader: 3 Replicas: 3,1,2 Isr: 3,1,2
Partition: 1 Leader: 1 Replicas: 1,2,3 Isr: 1,2,3
Partition: 2 Leader: 2 Replicas: 2,3,1 Isr: 2,3,1
Producer command:
./kafka-console-producer.sh \
--topic isr-error \
--bootstrap-server localhost:9092 \
--command-property acks=all \
--command-property request.timeout.ms=2000 \
--command-property delivery.timeout.ms=5000 \
--command-property retries=0
My understanding
From Kafka documentation and this explanation by Jun Rao (Kafka co-founder / Confluent):
Jun Rao explanation of min.insync.replicas
For writes with acks=all, produce requests should succeed only if:
ISR count >= min.insync.replicas
In my case:
ISR = 3
min.insync.replicas = 100
So:
3 >= 100 → false
Based on this, I expected produce requests to fail immediately with NotEnoughReplicasException.
Actual behavior
- Producing succeeded while all 3 brokers were alive.
- Consumer successfully received the messages.
Only after stopping one broker did produce requests fail with:
org.apache.kafka.common.errors.NotEnoughReplicasException:
Messages are rejected since there are fewer in-sync replicas than required.
Question
Why did Kafka accept produce requests earlier even though ISR (3) was already less than min.insync.replicas (100)?
Why was enforcement triggered only after a broker failure / ISR shrink event?
Am I misunderstanding how min.insync.replicas is enforced, or could this be specific to certain Kafka versions / KRaft / Docker setups?
For context:
- Kafka version: 4.2.0
- Mode: KRaft
- Docker image: apache/kafka:latest