{"id":"ba793084ead981bb","repo":"apache/kafka","slug":"invalid-negative-timestamp","errorCode":null,"errorMessage":"Invalid negative timestamp","messagePattern":"Invalid negative timestamp","errorType":"validation","errorClass":"java.lang.IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/clients/consumer/OffsetAndTimestamp.java","lineNumber":58,"sourceCode":"     */\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\n    /**\n     * Returns the offset.\n     *","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/clients/consumer/OffsetAndTimestamp.java#L40-L76","documentation":"IllegalArgumentException from the OffsetAndTimestamp constructor when timestamp is negative. The wrapper pairs a found offset with its event timestamp; negative timestamps are not valid message times (NO_TIMESTAMP is represented as 0, not negative), so construction fails fast.","triggerScenarios":"Calling new OffsetAndTimestamp(offset, timestamp, ...) with a negative timestamp, e.g. passing an error/sentinel time or a clock that underflowed.","commonSituations":"Translating a missing timestamp as -1 instead of 0/absent; arithmetic on message timestamps that goes negative; bridging from a system whose \"no-timestamp\" marker is negative.","solutions":["Use 0L (CreateTime.NO_TIMESTAMP) or skip construction when no timestamp is available.","Clamp or guard: only construct OffsetAndTimestamp when timestamp >= 0.","Fix the upstream source so its 'missing' value is not a negative long."],"exampleFix":"// before\nnew OffsetAndTimestamp(offset, -1L);\n\n// after\nif (ts < 0) ts = 0L; // or skip creating the instance\nnew OffsetAndTimestamp(offset, ts);","handlingStrategy":"validation","validationCode":"// OffsetAndTimestamp requires timestamp >= 0\nif (timestamp < 0) {\n    throw new IllegalArgumentException(\"OffsetAndTimestamp timestamp must be >= 0 (got \" + timestamp + \")\");\n}\nnew OffsetAndTimestamp(offset, timestamp, leaderEpoch);","typeGuard":null,"tryCatchPattern":"try {\n    new OffsetAndTimestamp(offset, timestamp, leaderEpoch);\n} catch (IllegalArgumentException e) {\n    if (\"Invalid negative timestamp\".equals(e.getMessage())) {\n        // use NO_TIMESTAMP (default -1/-1) handling: skip or fall back to wall-clock time\n    }\n    throw e;\n}","preventionTips":["Use TimestampType.NO_TIMESTAMP_TYPE semantics deliberately; do not pass -1 as a real timestamp.","When sourcing timestamps from user input or external clocks, clamp to System.currentTimeMillis() >= 0.","Document any sentinel (e.g. -1) at the boundary and translate it before constructing OffsetAndTimestamp."],"tags":["consumer","timestamp","validation"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}