quarkusio/quarkus · error · IllegalArgumentException
`timeout` must be positive
Error message
`timeout` must be positive
What it means
SetArgs.ex(long) sets the EX (seconds) option for a Redis SET command; the client requires a strictly positive value. Redis itself rejects non-positive expire times, so the Quarkus Redis client fails fast with IllegalArgumentException. Zero and negative values are both invalid.
Source
Thrown at extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/SetArgs.java:35
private long ex = -1;
private long exAt = -1;
private long px = -1;
private long pxAt = -1;
private boolean nx;
private boolean keepttl;
private boolean xx;
private boolean get;
/**
* Set the specified expire time, in seconds.
*
* @param timeout expire time in seconds.
* @return the current {@code GetExArgs}
*/
public SetArgs ex(long timeout) {
if (timeout <= 0) {
throw new IllegalArgumentException("`timeout` must be positive");
}
this.ex = timeout;
return this;
}
/**
* Sets the expiration.
*
* @param timeout expire time in seconds.
* @return the current {@code GetExArgs}
*/
public SetArgs ex(Duration timeout) {
if (timeout == null) {
throw new IllegalArgumentException("`timeout` must not be `null`");
}
return ex(timeout.toMillis() / 1000);
}
View on GitHub (pinned to e1c734241f)
Solutions
- Pass a value >= 1 second; clamp with Math.max(1, timeoutSeconds) if a minimum TTL is acceptable
- Only call ex() when the timeout is > 0: build args conditionally
- Fix the source of the value: validate configuration so a TTL of 0 means 'skip ex()' rather than reaching the setter
Example fix
// before
SetArgs args = SetArgs.args().ex(ttlSeconds); // throws when ttlSeconds <= 0
// after
SetArgs args = ttlSeconds > 0
? SetArgs.args().ex(ttlSeconds)
: SetArgs.args(); Defensive patterns
Strategy: validation
Validate before calling
if (ttlSeconds <= 0) {
throw new IllegalArgumentException("TTL must be positive, got: " + ttlSeconds);
}
SetArgs.args().ex(ttlSeconds); Try / catch
try {
args.ex(timeout);
} catch (IllegalArgumentException e) {
if (!e.getMessage().contains("`timeout` must be positive")) throw e;
args = SetArgs.args(); // proceed without expiry
} Prevention
- Treat TTL config value 0 as 'no expiry' and build args conditionally
- Validate TTL configuration at startup with @ConfigMapping validation
- Watch for negative results when computing TTL from timestamp differences
When it happens
Trigger: Calling SetArgs.ex(0) or ex(-n), usually from a timeout variable initialized to 0 or computed as a negative difference of timestamps.
Common situations: A configured TTL defaults to 0 meaning 'no expiry', but the code calls ex(0) unconditionally instead of skipping ex(); or a subtraction like (deadline - now) yields 0 or negative when the deadline already passed.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- `count` must be strictly positive
- `timeout` must not be `null`
- `timestamp` must not be `null`
- Channel cannot be blank
- `" + name + "` must not be `null`
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/88d34061a1976cfd.
Report an issue: GitHub.