kafka consumer "OffsetOutOfRangeException" reset strategy
Handles Kafka OffsetOutOfRangeException when a consumer's committed offset no longer exists. Use when log retention deleted the offset, when a consumer restarts after a long outage, and when choosing between earliest, latest, or failing fast. Not for rebalance storms or deserialization errors.
TL;DR
The consumer's committed offset points at log segments that retention already deleted. Pick a reset policy: earliest replays from the oldest retained offset, latest skips to the end, none throws so you can handle it yourself.
Error
org.apache.kafka.clients.consumer.OffsetOutOfRangeException: Offsets out of range with no configured reset policy for partitions: [orders-0]Steps
- Set
auto.offset.resetin the consumer config. This is the policy Kafka uses when the committed offset is gone:
auto.offset.reset=earliestExpected output: the consumer restarts from the oldest available offset instead of crashing.
- Choose deliberately.
earliestreplays everything retention still holds (safe, can be a huge backlog).latestskips to the end (fast, drops unprocessed messages).nonethrows OffsetOutOfRangeException so your code can decide per partition.
Expected output: a conscious tradeoff instead of the library default surprising you.
- For a one-off repair without changing config, seek manually after partition assignment:
consumer.seek(partition, earliest_available_offset)Expected output: consumption resumes from the offset you chose.
- Prevent recurrence: alert on consumer lag so a stalled consumer is noticed before retention deletes its offset.
Expected output: the outage that caused this gets caught in hours, not after the retention window passes.
When to use
- A consumer restarts after a long downtime and immediately throws OffsetOutOfRangeException
- Retention was shortened and consumers fell behind
- You are deciding the reset policy for a new consumer group
When not to use
- Rebalance loops or stuck partitions (thats group coordination, not offsets)
- Deserialization errors on current offsets (the offset exists; the bytes are the problem)
- You need exactly-once guarantees without idempotent handling (replay breaks that; fix the handling first)
Variant phrasings
"no offset stored" for a brand-new consumer group
Same setting applies: with no committed offset at all, auto.offset.reset decides where a new group starts.
out of range on a compacted topic
Compaction also removes offsets. earliest replays from the oldest compacted offset, which is usually what you want.
Why it happens
Kafka deletes log segments past the retention window, and committed offsets are just pointers into those segments. When the pointer's segment is gone, the offset is meaningless and the broker refuses it. The reset policy tells the consumer where to go instead.
Edge cases
earliestafter a month-long outage can replay millions of messages; make sure downstream handling is idempotent first.noneis the right choice for financial or exactly-once pipelines where silent skipping or replaying is unacceptable, but you must catch the exception.- Changing the policy does not move already-committed valid offsets; it only applies when the stored offset is missing or out of range.
Provenance
Resolved from the public thread: https://vectle.com/posts/pstE2aa9zf8V-1JPmZnEy0iA