apache/kafka · error · IllegalStateException
The partition {} does not have an end offset.
Error message
The partition {} does not have an end offset. What it means
Thrown by MockConsumer.endOffsets when a requested partition has no entry in the mock's endOffsets map. As with beginningOffsets, MockConsumer does not fetch from a broker; tests must seed end offsets via updateEndOffsets. Querying an unseeded partition is a test-setup error.
Source
Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/MockConsumer.java:662
if (beginningOffset == null)
throw new IllegalStateException("The partition " + tp + " does not have a beginning offset.");
result.put(tp, beginningOffset);
}
return result;
}
@Override
public synchronized Map<TopicPartition, Long> endOffsets(Collection<TopicPartition> partitions) {
if (offsetsException != null) {
RuntimeException exception = this.offsetsException;
this.offsetsException = null;
throw exception;
}
Map<TopicPartition, Long> result = new HashMap<>();
for (TopicPartition tp : partitions) {
Long endOffset = endOffsets.get(tp);
if (endOffset == null)
throw new IllegalStateException("The partition " + tp + " does not have an end offset.");
result.put(tp, endOffset);
}
return result;
}
@Override
public void close() {
close(CloseOptions.timeout(Duration.ofMillis(DEFAULT_CLOSE_TIMEOUT_MS)));
}
@Deprecated
@Override
public synchronized void close(Duration timeout) {
this.closed = true;
}
/**
* Returns whether this consumer has been closed.View on GitHub (pinned to 996fb4585a)
Solutions
- Call mock.updateEndOffsets(Map.of(tp, n)) for every partition queried.
- Seed both beginning and end offsets in a single setup helper to avoid asymmetry.
- Derive partition references from shared constants used in assign and seed.
Example fix
// before mock.assign(Set.of(tp)); Long end = mock.endOffsets(Set.of(tp)).get(tp); // throws // after mock.assign(Set.of(tp)); mock.updateEndOffsets(Map.of(tp, 100L)); Long end = mock.endOffsets(Set.of(tp)).get(tp);
Defensive patterns
Strategy: validation
Validate before calling
Set<TopicPartition> missing = partitions.stream()
.filter(tp -> !seededEndOffsets.containsKey(tp)).collect(Collectors.toSet());
if (!missing.isEmpty()) mockConsumer.updateEndOffsets(
missing.stream().collect(Collectors.toMap(tp -> tp, tp -> 0L)));
return mockConsumer.endOffsets(partitions); Type guard
static boolean allEndSeeded(MockConsumer<?,?> m, Collection<TopicPartition> tps) {
return knownEndSeed.containsAll(tps);
} Try / catch
try {
return mockConsumer.endOffsets(partitions);
} catch (IllegalStateException e) {
if (e.getMessage() != null && e.getMessage().contains("does not have an end offset")) {
mockConsumer.updateEndOffsets(partitions.stream().collect(Collectors.toMap(tp -> tp, tp -> 0L)));
return mockConsumer.endOffsets(partitions);
}
throw e;
} Prevention
- Seed end offsets in a single setup helper alongside beginning offsets.
- Use shared constants for partitions referenced in assign, beginningOffsets, endOffsets.
- Add a test setup helper that seeds the full boundary set for the assignment.
When it happens
Trigger: Calling endOffsets(tp) without updateEndOffsets(Map.of(tp, n)); partition mismatch between seed and query; tests that rely on consumer lag calculation without seeding end offsets.
Common situations: Tests for offset-based logic that forget the end-offset seed; refactor adding partitions without seeding; tests parameterized over partitions not all present in the seed.
Related errors
- You can only check the position for partitions assigned to t
- The partition {} does not have a beginning offset.
- MockConsumer didn't have beginning offset specified, but tri
- Cannot lose partitions that are not currently assigned: {not
- Cannot add records for a partition that is not assigned to t
AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11).
Data as JSON: /api/errors/08dc9649728d95ad.
Report an issue: GitHub.