{"record":{"id":"08dc9649728d95ad","repo":"apache/kafka","slug":"the-partition-does-not-have-an-end-offset","errorCode":null,"errorMessage":"The partition {} does not have an end offset.","messagePattern":"The partition (.+?) does not have an end offset\\.","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/MockConsumer.java","lineNumber":662,"sourceCode":"            if (beginningOffset == null)\n                throw new IllegalStateException(\"The partition \" + tp + \" does not have a beginning offset.\");\n            result.put(tp, beginningOffset);\n        }\n        return result;\n    }\n\n    @Override\n    public synchronized Map<TopicPartition, Long> endOffsets(Collection<TopicPartition> partitions) {\n        if (offsetsException != null) {\n            RuntimeException exception = this.offsetsException;\n            this.offsetsException = null;\n            throw exception;\n        }\n        Map<TopicPartition, Long> result = new HashMap<>();\n        for (TopicPartition tp : partitions) {\n            Long endOffset = endOffsets.get(tp);\n            if (endOffset == null)\n                throw new IllegalStateException(\"The partition \" + tp + \" does not have an end offset.\");\n            result.put(tp, endOffset);\n        }\n        return result;\n    }\n\n    @Override\n    public void close() {\n        close(CloseOptions.timeout(Duration.ofMillis(DEFAULT_CLOSE_TIMEOUT_MS)));\n    }\n\n    @Deprecated\n    @Override\n    public synchronized void close(Duration timeout) {\n        this.closed = true;\n    }\n\n    /**\n     * Returns whether this consumer has been closed.","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/apache/kafka/blob/996fb4585aa1bcc8980b0e1b8d6b168b986cd979/clients/src/main/java/org/apache/kafka/clients/consumer/MockConsumer.java#L644-L680","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nmock.assign(Set.of(tp));\nLong end = mock.endOffsets(Set.of(tp)).get(tp); // throws\n\n// after\nmock.assign(Set.of(tp));\nmock.updateEndOffsets(Map.of(tp, 100L));\nLong end = mock.endOffsets(Set.of(tp)).get(tp);","handlingStrategy":"validation","validationCode":"Set<TopicPartition> missing = partitions.stream()\n    .filter(tp -> !seededEndOffsets.containsKey(tp)).collect(Collectors.toSet());\nif (!missing.isEmpty()) mockConsumer.updateEndOffsets(\n    missing.stream().collect(Collectors.toMap(tp -> tp, tp -> 0L)));\nreturn mockConsumer.endOffsets(partitions);","typeGuard":"static boolean allEndSeeded(MockConsumer<?,?> m, Collection<TopicPartition> tps) {\n    return knownEndSeed.containsAll(tps);\n}","tryCatchPattern":"try {\n    return mockConsumer.endOffsets(partitions);\n} catch (IllegalStateException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"does not have an end offset\")) {\n        mockConsumer.updateEndOffsets(partitions.stream().collect(Collectors.toMap(tp -> tp, tp -> 0L)));\n        return mockConsumer.endOffsets(partitions);\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["consumer","mock-consumer","test","offsets","illegal-state"],"backgroundTag":null,"analyzedSha":"996fb4585aa1bcc8980b0e1b8d6b168b986cd979","analyzedAt":"2026-08-11T22:03:28.655Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}