apache/kafka · error · IllegalArgumentException
seek offset must not be a negative number
Error message
seek offset must not be a negative number
What it means
Thrown by seek(TopicPartition, long offset) when offset < 0. Kafka offsets are non-negative log positions; a negative offset is meaningless and would corrupt subscription fetch positions, so it is rejected before any subscription state mutation. The guard sits outside the acquireAndEnsureOpen lock so it fails fast.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/ClassicKafkaConsumer.java:797
}
@Override
public void commitAsync(final Map<TopicPartition, OffsetAndMetadata> offsets, OffsetCommitCallback callback) {
acquireAndEnsureOpen();
try {
throwIfGroupIdNotDefined();
log.debug("Committing offsets: {}", offsets);
offsets.forEach(this::updateLastSeenEpochIfNewer);
coordinator.commitOffsetsAsync(new HashMap<>(offsets), callback);
} finally {
release();
}
}
@Override
public void seek(TopicPartition partition, long offset) {
if (offset < 0)
throw new IllegalArgumentException("seek offset must not be a negative number");
acquireAndEnsureOpen();
try {
log.info("Seeking to offset {} for partition {}", offset, partition);
SubscriptionState.FetchPosition newPosition = new SubscriptionState.FetchPosition(
offset,
Optional.empty(), // This will ensure we skip validation
this.metadata.currentLeader(partition));
this.subscriptions.seekUnvalidated(partition, newPosition);
} finally {
release();
}
}
@Override
public void seek(TopicPartition partition, OffsetAndMetadata offsetAndMetadata) {
long offset = offsetAndMetadata.offset();
if (offset < 0) {View on GitHub (pinned to c31c9215e1)
Solutions
- Guard the offset before calling seek: if (offset < 0) use consumer.seekToBeginning / seekToEnd or position() instead.
- Fix the external offset store to return Optional.empty (or a clearly invalid sentinel handled explicitly) rather than -1.
- Initialize offsets to 0 (or use auto.offset.reset) so seek never receives a negative value.
Example fix
// before
long off = offsetStore.read(topic, partition); // returns -1 when missing
consumer.seek(new TopicPartition(topic, partition), off);
// after
long off = offsetStore.read(topic, partition);
TopicPartition tp = new TopicPartition(topic, partition);
if (off < 0) {
consumer.seekToBeginning(Collections.singletonList(tp));
} else {
consumer.seek(tp, off);
} Defensive patterns
Strategy: validation
Validate before calling
// long offset = ...
if (offset < 0) {
throw new IllegalArgumentException("seek offset must not be a negative number");
}
consumer.seek(partition, offset); Type guard
static long requireNonNegativeOffset(long offset) {
if (offset < 0) throw new IllegalArgumentException("seek offset must not be a negative number");
return offset;
} Try / catch
try {
consumer.seek(partition, offset);
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("negative number")) {
consumer.seek(partition, 0L); // clamp to earliest
} else throw e;
} Prevention
- Offset sources (DB, offset store) must be non-negative; validate before seek
- Use consumer.position(partition) as the source of truth rather than external guesses
- Guard seek against Long.MIN_MAX sentinels from deserialization
When it happens
Trigger: Calling consumer.seek(partition, -1) or passing a computed offset that underflows/was not initialized. Reading an offset from a store that returns -1 as a sentinel and forwarding it directly.
Common situations: Offset store returning -1 (or another negative sentinel) when no committed offset exists. Arithmetic underflow. Misconfigured external offset store (file, DB, Redis) with a default of -1.
Related errors
- seek offset must not be a negative number
- Invalid negative offset
- Invalid negative offset
- Partitions collection cannot be null
- Partitions collection cannot be null
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/3a653570bb73d9cc.json.
Report an issue: GitHub.