Skip to content

fix: Kafka offset reset - re-throw OffsetOutOfRangeException and fix metadata merge - #20092

Open
zhang-arvin wants to merge 1 commit into
apache:masterfrom
zhang-arvin:fix/issue-18282-kafka-offset-reset
Open

fix: Kafka offset reset - re-throw OffsetOutOfRangeException and fix metadata merge#20092
zhang-arvin wants to merge 1 commit into
apache:masterfrom
zhang-arvin:fix/issue-18282-kafka-offset-reset

Conversation

@zhang-arvin

Copy link
Copy Markdown

Description

Fixes #18282 - Kafka offset auto-reset behavior.

This PR makes three changes to improve how Kafka offset reset is handled:

1. KafkaIndexTaskRunner: Re-throw OffsetOutOfRangeException

Instead of swallowing the OffsetOutOfRangeException in getRecords() with possiblyResetOffsetsOrWait(), the exception is now re-thrown to let the supervisor handle the reset centrally. This aligns the Kafka task runner with the Kinesis task runner behavior.

2. SeekableStreamSupervisor.resetInternal: Fix metadata merge

Changed currentMetadata.minus(resetMetadata) to currentMetadata.plus(resetMetadata) when computing the new metadata during reset. The minus operation was incorrect — during reset, we need to add the reset partitions to the current metadata, not subtract them.

3. SeekableStreamSupervisor.createNewTasks: Emit alert instead of throwing

When partitions need reset in createNewTasks(), the code now emits an alert via log.makeAlert() instead of throwing a StreamException. This allows the task creation loop to continue processing other task groups after handling the reset.

@FrankChen021 FrankChen021 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Severity Findings
P0 0
P1 1
P2 2
P3 0
Total 3

Reviewed 2 of 2 changed files.


This is an automated review by Codex GPT-5.6-Luna(max)

metadataUpdateSuccess = true;
} else {
final DataSourceMetadata newMetadata = currentMetadata.minus(resetMetadata);
final DataSourceMetadata newMetadata = currentMetadata.plus(resetMetadata);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P1] Automatic reset retains the invalid checkpoint

When automatic reset handles a checkpoint below Kafka's earliest offset, plus preserves that invalid offset in metadata. The next run detects the same unavailable offset and resets it again forever instead of falling back to the stream's configured start position.

log.makeAlert(
"Previous sequenceNumbers are no longer available - automatically resetting sequences"
).addData("partitions", partitionsToReset).emit();
resetInternal(createDataSourceMetaDataForReset(ioConfig.getStream(), partitionsToReset));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P2] Pre-reset task groups omit reset partitions

newTaskGroups is built before resetInternal and excludes stale partitions. Since the exception was removed, those incomplete groups are still installed after reset; mixed groups omit the reset partition until rollover, while all-stale groups install an empty active group and create no task immediately.

log.warn("OffsetOutOfRangeException with message [%s]", e.getMessage());
possiblyResetOffsetsOrWait(e.offsetOutOfRangePartitions(), recordSupplier, toolbox);
return Collections.emptyList();
throw e;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[P2] Future offsets now fail instead of waiting

Kafka tasks use auto.offset.reset=none, so polling an offset beyond the current log end throws OffsetOutOfRangeException even when that offset is valid future work. The removed retry loop used to wait for records; rethrowing fails the task and can cause repeated retries until the log reaches that offset.

…metadata merge

- KafkaIndexTaskRunner: re-throw OffsetOutOfRangeException instead of
  swallowing it with possiblyResetOffsetsOrWait, letting the supervisor
  handle the reset centrally
- SeekableStreamSupervisor.resetInternal: use plus() instead of minus()
  when merging reset metadata with current metadata
- SeekableStreamSupervisor.createNewTasks: emit alert instead of throwing
  StreamException when partitions need reset
@zhang-arvin
zhang-arvin force-pushed the fix/issue-18282-kafka-offset-reset branch from f800295 to db737de Compare August 21, 2026 16:08
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.

Correctly reset kafka offset if auto reset is enabled

2 participants