quarkusio/quarkus · error · IllegalArgumentException

`timeout` must not be `null`

Error message

`timeout` must not be `null`

What it means

The deprecated GetExArgs.ex(Duration) converts the duration to seconds for the GETEX EX option; it requires a non-null Duration. Passing null would otherwise produce a NullPointerException later, so the method fails fast with this IllegalArgumentException.

Source

Thrown at extensions/redis-client/runtime/src/main/java/io/quarkus/redis/datasource/string/GetExArgs.java:43

     * Set the specified expire time, in seconds.
     *
     * @param timeout expire time in seconds.
     * @return the current {@code GetExArgs}
     */
    public GetExArgs ex(long timeout) {
        this.ex = timeout;
        return this;
    }

    /**
     * Sets the expiration.
     *
     * @param timeout expire time in seconds.
     * @return the current {@code GetExArgs}
     */
    public GetExArgs ex(Duration timeout) {
        if (timeout == null) {
            throw new IllegalArgumentException("`timeout` must not be `null`");
        }
        return ex(timeout.toMillis() / 1000);
    }

    /**
     * Sets the expiration time
     *
     * @param timestamp the timestamp
     * @return the current {@code GetExArgs}
     */
    public GetExArgs exAt(long timestamp) {
        this.exAt = timestamp;
        return this;
    }

    /**
     * Sets the expiration time
     *

View on GitHub (pinned to e1c734241f)

Solutions

  1. Pass a concrete non-null Duration, e.g. GetExArgs.ex(Duration.ofSeconds(60))
  2. If the TTL is optional, guard with a null check and skip the getex or use persist()/a default TTL
  3. Prefer the long overload ex(long) with a computed value when the source may be null

Example fix

// before
Duration ttl = config.get("ttl", Duration.class); // may be null
args.ex(ttl);
// after
Duration ttl = config.get("ttl", Duration.class);
if (ttl != null) {
    args.ex(ttl);
}
Defensive patterns

Strategy: validation

Validate before calling

if (timeout == null) {
    throw new IllegalArgumentException("TTL must be provided for GETEX ex()");
}

Type guard

boolean hasTtl(Duration d) {
    return d != null && !d.isNegative() && !d.isZero();
}

Try / catch

try {
    redis.string().getex(key, new GetExArgs().ex(ttl));
} catch (IllegalArgumentException e) {
    log.warn("GETEX skipped: " + e.getMessage());
}

Prevention

When it happens

Trigger: Calling GetExArgs.ex((Duration) null) directly, or passing a Duration variable that resolved to null (e.g. from an Optional.get()/config lookup that was absent) into ex(Duration) when building args for a getex command.

Common situations: Expiration durations pulled from configuration or environment that are unset/null; optional TTL values that were not defaulted before constructing the args.

Understand the failure class

Related errors


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