quarkusio/quarkus · error · java.lang.IllegalArgumentException

Delay must be > 0: <delay>

Error message

Delay must be > 0: <delay>

What it means

SseEventSourceBuilderImpl.reconnectingEvery validates the SSE reconnect delay before storing it and throws this IllegalArgumentException if the delay is not strictly positive. The delay controls how long the client waits before reconnecting after an SSE stream drops.

Source

Thrown at independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/SseEventSourceBuilderImpl.java:27

public class SseEventSourceBuilderImpl extends SseEventSource.Builder {

    private WebTarget endpoint;
    // defaults set by spec
    private TimeUnit reconnectUnit = TimeUnit.MILLISECONDS;
    private long reconnectDelay = 500;

    @Override
    protected Builder target(WebTarget endpoint) {
        this.endpoint = endpoint;
        return this;
    }

    @Override
    public Builder reconnectingEvery(long delay, TimeUnit unit) {
        Objects.requireNonNull(unit);
        if (delay <= 0)
            throw new IllegalArgumentException("Delay must be > 0: " + delay);
        this.reconnectDelay = delay;
        this.reconnectUnit = unit;
        return this;
    }

    @Override
    public SseEventSource build() {
        return new SseEventSourceImpl((WebTargetImpl) endpoint, endpoint.request(), reconnectDelay, reconnectUnit);
    }

}

View on GitHub (pinned to e1c734241f)

Solutions

  1. Pass a strictly positive delay, e.g. reconnectingEvery(1, TimeUnit.SECONDS)
  2. Clamp the configured value: if (delay <= 0) delay = DEFAULT_RECONNECT_DELAY;
  3. Fix the unit conversion so the numeric value is positive before the call

Example fix

// before
long delay = TimeUnit.MILLISECONDS.toSeconds(500); // 0
builder.reconnectingEvery(delay, TimeUnit.SECONDS);
// after
builder.reconnectingEvery(500, TimeUnit.MILLISECONDS);
Defensive patterns

Strategy: validation

Validate before calling

if (unit == null) throw new IllegalArgumentException("unit required");
long millis = unit.toMillis(delay);
if (delay <= 0 || millis <= 0) {
    delay = 1; millis = 1; // clamp to minimum
}
builder.reconnectingEvery(delay, unit);

Type guard

boolean isValidReconnectDelay(long delay, TimeUnit unit) {
    return unit != null && delay > 0;
}

Try / catch

try {
    builder.reconnectingEvery(delay, unit);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Delay must be > 0")) {
        builder.reconnectingEvery(1, TimeUnit.SECONDS); // safe default
    } else throw e;
}

Prevention

When it happens

Trigger: Calling builder.reconnectingEvery(0, TimeUnit.SECONDS) or a negative delay on a WebTarget's SseEventSource.Builder; passing a computed/variable delay that ended up <= 0 (e.g. Math.round of a small fraction).

Common situations: Config value parsed from properties defaulting to 0 when unset; computing delay from milliseconds division that truncates to 0; passing delay in the wrong unit (ms value used as seconds then converted to 0).

Related errors


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