Kafka troubleshooting
OutOfOrderSequenceException (OUT_OF_ORDER_SEQUENCE_NUMBER)
org.
The partition leader received a batch whose sequence number does not follow the last one it stored for this producer, so it refused to append it rather than leave a gap. It usually means the broker lost records the producer had already written. Find that loss first; for a transactional producer, closing and recreating it is the safe response.
Reproduce it in the playground3 steps beforeLost ack → p-idem re-sends seq 0 → DEDUPED (no second write). t+3.100s
Idempotence: the broker recognises the already-committed sequence and acks without appending. Still one record.
Open at this step: step 3, Lost ack → p-idem re-sends seq 0 → DEDUPED (no second write)2 steps beforep-plain commits X at offset 1. t+5.100s
Open at this step: step 4, p-plain commits X at offset 11 step beforeLost ack → p-plain re-sends → DUPLICATE at offset 2. t+7.100s
No idempotence: the retry writes a second copy. The same record now sits at offsets 1 and 2.
Open at this step: step 5, Lost ack → p-plain re-sends → DUPLICATE at offset 2The moment it happensDropped batch left a gap → p-idem hits OUT_OF_ORDER_SEQUENCE_NUMBER (producer stops). t+11.100s
A batch the broker never received left a gap after the last accepted sequence, so the broker rejects the next batch with OUT_OF_ORDER_SEQUENCE_NUMBER. The simulator stops the producer here, as a transactional producer would have to; a Kafka 4.x idempotent producer instead bumps its epoch, resets the sequence and retries on its own.
Open at this step: step 6, Dropped batch left a gap → p-idem hits OUT_OF_ORDER_SEQUENCE_NUMBER (producer stops)What it means
An idempotent producer, the default when no conflicting settings are given, stamps every batch with its producer id, an epoch and a sequence number per partition. The leader remembers the last sequences it accepted and appends a batch only if its sequence is the next one: a duplicate is acknowledged without being written again, and a gap is rejected with OUT_OF_ORDER_SEQUENCE_NUMBER (error code 45). The Javadoc spells out what that implies: data may have been lost. The leader logs the rejection at ERROR, "Error processing append operation on partition ...orders-0", with the exception "org.apache.kafka.common.errors.OutOfOrderSequenceException: Out of order sequence number for producer 1000 at offset 42 in partition orders-0: 7 (incoming seq. number), 4 (current end sequence number)". An idempotent producer without a transactional.id logs "The broker returned org.apache.kafka.common.errors.OutOfOrderSequenceException: ... for topic-partition orders-0 with producerId 1000, epoch 0, and sequence number 7". The producer first retries batches that were out of order only because an earlier one was still in flight. When the gap is real, an idempotent producer without a transactional.id bumps its epoch and restarts that partition at sequence 0, so it keeps sending, but records that were pending may land out of order. For a transactional producer the KafkaProducer Javadoc says the only option left is close(); the 4.3 client treats the error as abortable, but closing is the safe advice. UnknownProducerIdException, the error for a producer id the broker has no state for, is a subclass, so a catch block for OutOfOrderSequenceException catches it too.
Likely causes, most common first
- The leader lost acknowledged records. After a leader change the new leader may lack batches the old one acknowledged: with acks=1, or acks=all and min.insync.replicas=1, a write can be acknowledged by the leader alone, and an unclean leader election (unclean.leader.election.enable=true) can elect a replica that is missing records. The producer's next sequence then sits beyond the new leader's last one.
- A batch expired while later ones were in flight. With up to five requests in flight per connection, a batch that hits delivery.timeout.ms after it was sent leaves the producer unsure whether the broker stored it. The batches already in flight behind it may then no longer line up with what the broker holds, and the producer waits for them to resolve before it sends more to that partition.
How to fix it
- Look for the loss first: check whether the partition changed leader around the time of the error, whether unclean leader election is enabled for the topic, and the producer log for "Got error produce response ... Error: OUT_OF_ORDER_SEQUENCE_NUMBER".
- Make acknowledged writes survive a leader change: acks=all, replication factor 3 with min.insync.replicas of at least 2, and unclean.leader.election.enable=false, the default.
- Transactional producer: close() it, create a new one with the same transactional.id (initTransactions() aborts the unfinished transaction) and reprocess from the last committed offsets.
- Idempotent producer: it usually retries past the gap after an epoch bump, so the application often sees no exception; if one surfaces and ordering matters, close and recreate it as the Javadoc advises. Scenario 01.3.3 stops the producer here, the response the Javadoc gives for a transactional producer; a real idempotent producer would carry on.
- Keep max.in.flight.requests.per.connection at 5 or less and retries above 0, as idempotence requires, and give delivery.timeout.ms enough room that batches rarely expire while in flight.
What not to do
- Turning off enable.idempotence to stop the error: the gap does not go away, it turns into silent duplicates and reordering on retry.
Does the client retry it?
Not as the same request. The exception is not a RetriableException, but an idempotent producer in Kafka 4.x usually recovers by itself: it bumps its epoch, restarts the partition's sequence at 0 and sends again. For a transactional producer the safe response is to close it and create a new one, as the Javadoc advises, although the 4.3 client itself only marks the transaction as abortable.
Configs involved
enable.Gives the producer an id and a sequence number per partition so the broker drops duplicate retries and keeps them in order; on by default unless a conflicting setting (acks other than all, retries=0, more than 5 in-flight requests) turns it off.idempotence max.How many unacknowledged requests the producer sends on one connection (default 5); above 1 without idempotence a retried batch can land after a later one, and idempotence needs 5 or fewer.in. flight. requests. per. connection retriesHow many times the producer sends a batch again after a transient error (default 2147483647, so in practice delivery.timeout.ms ends the retrying); idempotence needs it above 0.acksHow many replicas must have a write before the producer counts it as sent: 0 (none), 1 (the leader only) or all (every in-sync replica, the default, and required for idempotence).min.The fewest in-sync replicas, leader included, that must have a write for an acks=all produce to succeed (default 1); with fewer in the ISR the leader rejects the write with NOT_ENOUGH_REPLICAS.insync. replicas unclean.Lets a replica that is not in the ISR become leader when no in-sync replica is left, which brings the partition back online but loses the writes that replica never received (default false).leader. election. enable delivery.The upper bound on reporting success or failure after send() returns, covering the wait in a batch, the wait for the acknowledgement and every retry (default 120000, 2 minutes); it should be at least request.timeout.ms plus linger.ms.timeout. ms
Reproduce it in the simulator
- Kafka idempotent producer dedup vs a plain producer (Idempotent dedup vs duplicate) Open at the moment it happens: Kafka idempotent producer dedup vs a plain producer
Sources
- Apache Kafka 4.3 Javadoc: OutOfOrderSequenceException
- Apache Kafka 4.3 Javadoc: KafkaProducer (send errors with idempotence and transactions)
- Apache Kafka 4.3.0 source: Errors.java (OUT_OF_ORDER_SEQUENCE_NUMBER, code 45)
- Apache Kafka 4.3.0 source: Sender.java (in-flight batches that expire)
- Apache Kafka 4.3.0 source: TransactionManager.java (epoch bump on a sequence gap)
- Apache Kafka 4.3: producer config enable.idempotence
- Apache Kafka 4.3: producer config max.in.flight.requests.per.connection
- Apache Kafka 4.3: producer config acks
- Apache Kafka 4.3: unclean leader election
- Apache Kafka 4.3.0 source: ProducerAppendInfo.java (Out of order sequence number for producer)
- Apache Kafka 4.3.0 source: ReplicaManager.scala (Error processing append operation on partition)