{"record":{"id":"7eafb345cfb6fb03","repo":"apache/kafka","slug":"mockconsumer-didn-t-have-beginning-offset-specifie","errorCode":null,"errorMessage":"MockConsumer didn't have beginning offset specified, but tried to seek to beginning","messagePattern":"MockConsumer didn't have beginning offset specified, but tried to seek to beginning","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/MockConsumer.java","lineNumber":742,"sourceCode":"\n    private void updateFetchPosition(TopicPartition tp) {\n        if (subscriptions.isOffsetResetNeeded(tp)) {\n            resetOffsetPosition(tp);\n        } else if (!committed.containsKey(tp)) {\n            subscriptions.requestOffsetReset(tp);\n            resetOffsetPosition(tp);\n        } else {\n            subscriptions.seek(tp, committed.get(tp).offset());\n        }\n    }\n\n    private void resetOffsetPosition(TopicPartition tp) {\n        AutoOffsetResetStrategy strategy = subscriptions.resetStrategy(tp);\n        Long offset;\n        if (strategy == AutoOffsetResetStrategy.EARLIEST) {\n            offset = beginningOffsets.get(tp);\n            if (offset == null)\n                throw new IllegalStateException(\"MockConsumer didn't have beginning offset specified, but tried to seek to beginning\");\n        } else if (strategy == AutoOffsetResetStrategy.LATEST) {\n            offset = endOffsets.get(tp);\n            if (offset == null)\n                throw new IllegalStateException(\"MockConsumer didn't have end offset specified, but tried to seek to end\");\n        } else if (strategy.type() == AutoOffsetResetStrategy.StrategyType.BY_DURATION) {\n            offset = durationResetOffsets.get(tp);\n            if (offset == null)\n                throw new IllegalStateException(\"MockConsumer didn't have duration offset specified, but tried to seek to timestamp\");\n        } else {\n            throw new NoOffsetForPartitionException(tp);\n        }\n        seek(tp, offset);\n    }\n\n    @Override\n    public List<PartitionInfo> partitionsFor(String topic, Duration timeout) {\n        return partitionsFor(topic);\n    }","sourceCodeStart":724,"sourceCodeEnd":760,"githubUrl":"https://github.com/apache/kafka/blob/996fb4585aa1bcc8980b0e1b8d6b168b986cd979/clients/src/main/java/org/apache/kafka/clients/consumer/MockConsumer.java#L724-L760","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Call mock.updateBeginningOffsets(Map.of(tp, 0L)) for partitions consumed with earliest reset.","If you do not need reset behavior, commit an offset for the partition so reset is not triggered.","Seed both beginning and end offsets whenever auto.offset.reset may apply."],"exampleFix":"// before\nprops.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, \"earliest\");\nmock.assign(Set.of(tp));\nmock.poll(Duration.ofMillis(100)); // throws: no beginning offset\n\n// after\nmock.assign(Set.of(tp));\nmock.updateBeginningOffsets(Map.of(tp, 0L));\nmock.poll(Duration.ofMillis(100));","handlingStrategy":"validation","validationCode":"// ensure a beginning offset exists for any partition consumed with earliest reset\nfor (TopicPartition tp : mockConsumer.assignment()) {\n    if (!seededBeginningOffsets.containsKey(tp))\n        mockConsumer.updateBeginningOffsets(Map.of(tp, 0L));\n}","typeGuard":"static boolean earliestResetCovered(MockConsumer<?,?> m, Set<TopicPartition> tps) {\n    return knownBeginningSeed.containsAll(tps);\n}","tryCatchPattern":"try {\n    return mockConsumer.poll(Duration.ofMillis(100));\n} catch (IllegalStateException e) {\n    if (\"MockConsumer didn't have beginning offset specified, but tried to seek to beginning\".equals(e.getMessage())) {\n        mockConsumer.updateBeginningOffsets(currentAssignment().stream().collect(Collectors.toMap(tp -> tp, tp -> 0L)));\n        return mockConsumer.poll(Duration.ofMillis(100));\n    }\n    throw e;\n}","preventionTips":["Seed beginning offsets whenever auto.offset.reset=earliest may apply.","Commit offsets explicitly when you want to bypass reset behavior.","Add a setup helper that seeds both beginning and end offsets for the assignment."],"tags":["consumer","mock-consumer","test","offsets","auto-offset-reset","illegal-state"],"backgroundTag":null,"analyzedSha":"996fb4585aa1bcc8980b0e1b8d6b168b986cd979","analyzedAt":"2026-08-11T22:03:28.655Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}