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

  1. Call mock.updateEndOffsets(Map.of(tp, n)) for every partition queried.
  2. Seed both beginning and end offsets in a single setup helper to avoid asymmetry.
  3. 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

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


AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11). Data as JSON: /api/errors/08dc9649728d95ad. Report an issue: GitHub.