Skip to content

Conversation

@twmb
Copy link
Owner

@twmb twmb commented Dec 12, 2025

MarkCommit{Records,Offsets} compared the epoch/offset you were marking against the existing head epoch/offset. If the there was no internally existing epoch/offset, or only dirty was set (via being consumed) while head / committed were both the default struct value {0,0}, then trying to mark a record with a negative epoch would be ignored.

Note that returning -1 via the broker epoch requires a broker to both (a) SUPPORT epochs, i.e. implement all the Kafka APIs with leader epoch support, and then (b) NOT SUPPORT epochs, i.e. return / use -1 everywhere. This has only been seen against Azure Event hubs.

Anyway, now, when initializing an EpochOffset internally (for an uncommit {dirty,head,committed}, the epoch is explicitly initialized with -1. Further, for added robustness, MarkCommit{Records,Offsets} only compares against existing values -- if a value does not exist, we auto-accept the mark.

This commit also:

  • Improves EpochOffset.Less to assume all negative epochs are -1
  • Simplifies the logic in CommitRecords to use EpochOffset.Less
  • Adds debug lines in metadata when new partitions are added
  • Adds the epoch to an existing debug log line when updating uncommitted
  • Sets the LeaderEpoch to -1 for records when producing, and clarifies in docs that -1 should have always been the case.

MarkCommit{Records,Offsets} compared the epoch/offset you were marking
against the existing head epoch/offset. If the there was no internally
existing epoch/offset, or only `dirty` was set (via being consumed)
while `head` / `committed` were both the default struct value {0,0},
then trying to mark a record with a negative epoch would be ignored.

Note that returning -1 via the broker epoch requires a broker to both
(a) SUPPORT epochs, i.e. implement all the Kafka APIs with leader epoch
support, and then (b) NOT SUPPORT epochs, i.e. return / use -1
everywhere. This has only been seen against Azure Event hubs.

Anyway, now, when initializing an EpochOffset internally (for an
uncommit {dirty,head,committed}, the epoch is explicitly initialized
with -1. Further, for added robustness, MarkCommit{Records,Offsets}
only compares against existing values -- if a value does not exist,
we auto-accept the mark.

This commit also:
* Improves EpochOffset.Less to assume all negative epochs are -1
* Simplifies the logic in CommitRecords to use EpochOffset.Less
* Adds debug lines in metadata when new partitions are added
* Adds the epoch to an existing debug log line when updating uncommitted
* Sets the LeaderEpoch to -1 for records when producing, and clarifies
  in docs that -1 should have always been the case.
Copy link
Contributor

@rockwotj rockwotj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. Makes sense

@twmb twmb merged commit 7cd5ea6 into master Dec 20, 2025
16 checks passed
@twmb twmb deleted the epoch branch December 20, 2025 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants