quarkusio/quarkus · error · IllegalArgumentException

The timestamp must be positive

Error message

The timestamp must be positive

What it means

MRangeArgs.filterByTimestamp(long...) filters TS_MRANGE samples to the given timestamps. RedisTimeSeries timestamps are non-negative epoch millis, so any negative value is rejected with IllegalArgumentException before the command is sent. Zero is allowed; only negative values fail.

Source

Thrown at extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/timeseries/MRangeArgs.java:61

    public MRangeArgs latest() {
        this.latest = true;
        return this;
    }

    /**
     * Filters samples by a list of specific timestamps.
     * A sample passes the filter if its exact timestamp is specified and falls within [fromTimestamp, toTimestamp].
     *
     * @param timestamps the timestamps
     * @return the current {@code MRangeArgs}
     */
    public MRangeArgs filterByTimestamp(long... timestamps) {
        if (filterByTimestamps == null) {
            filterByTimestamps = new ArrayList<>(timestamps.length);
        }
        for (long timestamp : timestamps) {
            if (timestamp < 0) {
                throw new IllegalArgumentException("The timestamp must be positive");
            }
            filterByTimestamps.add(timestamp);
        }
        return this;
    }

    /**
     * Filters samples by minimum and maximum values.
     *
     * @param min the min value of the sample
     * @param max the max value of the sample
     * @return the current {@code MRangeArgs}
     */
    public MRangeArgs filterByValue(double min, double max) {
        this.filterByValue = true;
        this.min = min;
        this.max = max;

View on GitHub (pinned to e1c734241f)

Solutions

  1. Filter out negative values before calling: long[] valid = Arrays.stream(ts).filter(t -> t >= 0).toArray()
  2. Fix the computation producing the negative timestamp (e.g. clamp to 0)
  3. Replace -1 sentinels with a proper Optional/absence representation instead of passing them to filterByTimestamp

Example fix

// before
args.filterByTimestamp(sinceMillis - lookback); // can go negative
// after
long from = Math.max(0, sinceMillis - lookback);
args.filterByTimestamp(from);
Defensive patterns

Strategy: validation

Validate before calling

long[] safe = Arrays.stream(timestamps)
    .peek(t -> { if (t < 0) throw new IllegalArgumentException("negative timestamp: " + t); })
    .toArray();
args.filterByTimestamp(safe);

Type guard

boolean allTimestampsValid(long... ts) {
    return ts == null || Arrays.stream(ts).allMatch(t -> t >= 0);
}

Try / catch

try {
    args.filterByTimestamp(timestamps);
} catch (IllegalArgumentException e) {
    log.warn("Skipping invalid timestamp filter: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling filterByTimestamp with any negative long — e.g. filterByTimestamp(-1), or computed values like System.currentTimeMillis() - duration where duration exceeds the epoch time, or sentinel values like -1 used to mean 'unset'.

Common situations: Using -1 as a 'no timestamp' sentinel; subtracting a too-large offset from currentTimeMillis(); receiving negative timestamps from upstream data or misparsed dates.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/dcddf2551725b040. Report an issue: GitHub.