apache/kafka · error · IllegalArgumentException

Invalid negative timestamp

Error message

Invalid negative timestamp

What it means

OffsetAndTimestamp constructor (same site as error 106) also enforces timestamp >= 0. Kafka record timestamps are non-negative epoch millis, so a negative timestamp would be meaningless as a seek target. The check throws IllegalArgumentException before assignment.

Solutions

  1. Return null for unmatched partitions rather than constructing OffsetAndTimestamp with a sentinel timestamp.
  2. Verify timestamp >= 0 (and ideally within a sane epoch range) before constructing.
  3. When faking offsetsForTimes results in tests, use real epoch millis (e.g., System.currentTimeMillis()).

Example fix

// before
new OffsetAndTimestamp(5L, -1L, Optional.empty()); // -> IllegalArgumentException

// after
new OffsetAndTimestamp(5L, System.currentTimeMillis(), Optional.empty());
Defensive patterns

Strategy: validation

Validate before calling

if (timestamp < 0) return null;
return new OffsetAndTimestamp(offset, timestamp, leaderEpoch);

Type guard

static boolean isValidTimestamp(long ts) { return ts >= 0; }

Try / catch

null

Prevention

When it happens

Trigger: new OffsetAndTimestamp(offset, -1L, leaderEpoch); or faking a result where the matched record's timestamp is unknown.

Common situations: Test doubles mocking offsetsForTimes with placeholder timestamps; misinterpreting a 'no match' as a sentinel timestamp; clock skew producing negative epoch values.

Related errors


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

Appendix: source

Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/OffsetAndTimestamp.java:58

     */
    public OffsetAndTimestamp(long offset, long timestamp) {
        this(offset, timestamp, Optional.empty());
    }

    /**
     * Constructs a new OffsetAndTimestamp with the given offset, timestamp, and leader epoch.
     *
     * @param offset The offset
     * @param timestamp The timestamp
     * @param leaderEpoch The leader epoch
     * @throws IllegalArgumentException If the offset or timestamp is negative
     */
    public OffsetAndTimestamp(long offset, long timestamp, Optional<Integer> leaderEpoch) {
        if (offset < 0)
            throw new IllegalArgumentException("Invalid negative offset");

        if (timestamp < 0)
            throw new IllegalArgumentException("Invalid negative timestamp");

        this.offset = offset;
        this.timestamp = timestamp;
        this.leaderEpoch = leaderEpoch;
    }

    /**
     * Returns the timestamp.
     *
     * @return The timestamp
     */
    public long timestamp() {
        return timestamp;
    }

    /**
     * Returns the offset.
     *

View on GitHub (pinned to 996fb4585a)