{"record":{"id":"13fc871015a27ce7","repo":"apache/kafka","slug":"invalid-negative-offset-13fc87","errorCode":null,"errorMessage":"Invalid negative offset","messagePattern":"Invalid negative offset","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/OffsetAndTimestamp.java","lineNumber":55,"sourceCode":"     * @param offset The offset\n     * @param timestamp The timestamp\n     * @throws IllegalArgumentException If the offset or timestamp is negative\n     */\n    public OffsetAndTimestamp(long offset, long timestamp) {\n        this(offset, timestamp, Optional.empty());\n    }\n\n    /**\n     * Constructs a new OffsetAndTimestamp with the given offset, timestamp, and leader epoch.\n     *\n     * @param offset The offset\n     * @param timestamp The timestamp\n     * @param leaderEpoch The leader epoch\n     * @throws IllegalArgumentException If the offset or timestamp is negative\n     */\n    public OffsetAndTimestamp(long offset, long timestamp, Optional<Integer> leaderEpoch) {\n        if (offset < 0)\n            throw new IllegalArgumentException(\"Invalid negative offset\");\n\n        if (timestamp < 0)\n            throw new IllegalArgumentException(\"Invalid negative timestamp\");\n\n        this.offset = offset;\n        this.timestamp = timestamp;\n        this.leaderEpoch = leaderEpoch;\n    }\n\n    /**\n     * Returns the timestamp.\n     *\n     * @return The timestamp\n     */\n    public long timestamp() {\n        return timestamp;\n    }\n","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/apache/kafka/blob/996fb4585aa1bcc8980b0e1b8d6b168b986cd979/clients/src/main/java/org/apache/kafka/clients/consumer/OffsetAndTimestamp.java#L37-L73","documentation":"OffsetAndTimestamp is the result type returned by KafkaConsumer.offsetsForTimes(...) - it pairs an offset with the timestamp of the first record at or after the requested time. Its constructor validates offset >= 0 (and separately timestamp >= 0) and throws IllegalArgumentException otherwise, because the consumer API contract guarantees non-negative offsets for matched records.","triggerScenarios":"Direct construction new OffsetAndTimestamp(-1L, timestamp, leaderEpoch). Not normally reachable from offsetsForTimes because the consumer only produces OffsetAndTimestamp for matched (offset>=0) records; it appears when application code wraps/fakes results.","commonSituations":"Custom test fakes that build OffsetAndTimestamp with placeholder -1; mapping code that passes through an 'unmatched' marker instead of returning null/empty from offsetsForTimes.","solutions":["Return null from offsetsForTimes mappings for partitions with no match instead of constructing OffsetAndTimestamp with -1.","Guard offset >= 0 before constructing; use Optional<OffsetAndTimestamp> at API boundaries if you need to express absence.","Audit wrappers around offsetsForTimes results that reinterpret 'no match' as a sentinel."],"exampleFix":"// before\nOffsetAndTimestamp r = matched != null ? new OffsetAndTimestamp(matched.offset(), matched.timestamp(), leaderEpoch)\n                                      : new OffsetAndTimestamp(-1L, -1L, leaderEpoch); // -> IllegalArgumentException\n\n// after\nOffsetAndTimestamp r = matched != null ? new OffsetAndTimestamp(matched.offset(), matched.timestamp(), leaderEpoch)\n                                      : null;","handlingStrategy":"validation","validationCode":"if (offset < 0) return null;  // represent 'no match' as absence\nreturn new OffsetAndTimestamp(offset, timestamp, leaderEpoch);","typeGuard":"static boolean isResultOffset(long offset) { return offset >= 0; }","tryCatchPattern":"null","preventionTips":["Return null from offsetsForTimes mappings for unmatched partitions.","Do not fake OffsetAndTimestamp with negative offsets in test doubles."],"tags":["consumer","offsets-for-times","validation","kafka-clients"],"backgroundTag":null,"analyzedSha":"996fb4585aa1bcc8980b0e1b8d6b168b986cd979","analyzedAt":"2026-08-11T22:03:28.655Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}