apache/kafka · error · IllegalStateException

MockConsumer didn't have beginning offset specified, but tri

Error message

MockConsumer didn't have beginning offset specified, but tried to seek to beginning

What it means

Thrown by MockConsumer.resetOffsetPosition when an offset reset is needed (no committed offset) with strategy EARLIEST, but the mock has no beginning offset seeded for that partition. The mock cannot fabricate a beginning offset (it has no broker), so the test must seed one. Mirrors the real consumer's NoOffsetForPartition behavior but specific to the missing seed.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/MockConsumer.java:742

    private void updateFetchPosition(TopicPartition tp) {
        if (subscriptions.isOffsetResetNeeded(tp)) {
            resetOffsetPosition(tp);
        } else if (!committed.containsKey(tp)) {
            subscriptions.requestOffsetReset(tp);
            resetOffsetPosition(tp);
        } else {
            subscriptions.seek(tp, committed.get(tp).offset());
        }
    }

    private void resetOffsetPosition(TopicPartition tp) {
        AutoOffsetResetStrategy strategy = subscriptions.resetStrategy(tp);
        Long offset;
        if (strategy == AutoOffsetResetStrategy.EARLIEST) {
            offset = beginningOffsets.get(tp);
            if (offset == null)
                throw new IllegalStateException("MockConsumer didn't have beginning offset specified, but tried to seek to beginning");
        } else if (strategy == AutoOffsetResetStrategy.LATEST) {
            offset = endOffsets.get(tp);
            if (offset == null)
                throw new IllegalStateException("MockConsumer didn't have end offset specified, but tried to seek to end");
        } else if (strategy.type() == AutoOffsetResetStrategy.StrategyType.BY_DURATION) {
            offset = durationResetOffsets.get(tp);
            if (offset == null)
                throw new IllegalStateException("MockConsumer didn't have duration offset specified, but tried to seek to timestamp");
        } else {
            throw new NoOffsetForPartitionException(tp);
        }
        seek(tp, offset);
    }

    @Override
    public List<PartitionInfo> partitionsFor(String topic, Duration timeout) {
        return partitionsFor(topic);
    }

View on GitHub (pinned to 996fb4585a)

Solutions

  1. Call mock.updateBeginningOffsets(Map.of(tp, 0L)) for partitions consumed with earliest reset.
  2. If you do not need reset behavior, commit an offset for the partition so reset is not triggered.
  3. Seed both beginning and end offsets whenever auto.offset.reset may apply.

Example fix

// before
props.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
mock.assign(Set.of(tp));
mock.poll(Duration.ofMillis(100)); // throws: no beginning offset

// after
mock.assign(Set.of(tp));
mock.updateBeginningOffsets(Map.of(tp, 0L));
mock.poll(Duration.ofMillis(100));
Defensive patterns

Strategy: validation

Validate before calling

// ensure a beginning offset exists for any partition consumed with earliest reset
for (TopicPartition tp : mockConsumer.assignment()) {
    if (!seededBeginningOffsets.containsKey(tp))
        mockConsumer.updateBeginningOffsets(Map.of(tp, 0L));
}

Type guard

static boolean earliestResetCovered(MockConsumer<?,?> m, Set<TopicPartition> tps) {
    return knownBeginningSeed.containsAll(tps);
}

Try / catch

try {
    return mockConsumer.poll(Duration.ofMillis(100));
} catch (IllegalStateException e) {
    if ("MockConsumer didn't have beginning offset specified, but tried to seek to beginning".equals(e.getMessage())) {
        mockConsumer.updateBeginningOffsets(currentAssignment().stream().collect(Collectors.toMap(tp -> tp, tp -> 0L)));
        return mockConsumer.poll(Duration.ofMillis(100));
    }
    throw e;
}

Prevention

When it happens

Trigger: Consuming from a partition with no committed offset and auto.offset.reset=earliest, without calling updateBeginningOffsets for that partition; tests that rely on offset reset but forgot to seed the corresponding boundary.

Common situations: Tests for reset behavior that seed only end offsets; refactor that changed default reset strategy to earliest without seeding beginnings; assignment of new partitions after a rebalance without seeding.

Related errors


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