eclipse-vertx/vert.x · error · IllegalArgumentException
Timeout must be >= 0
Error message
Timeout must be >= 0
What it means
Http3Connection.shutdown(Duration) validates that the shutdown timeout is not negative before delegating to the QUIC connection shutdown. A negative Duration is meaningless for a timeout, so IllegalArgumentException is thrown immediately.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/http3/Http3Connection.java:269
vSetting = Http3Settings.MAX_FIELD_SECTION_SIZE;
break;
default:
continue;
}
vSettings.setLong(vSetting, setting.getValue());
}
}
remoteSettings = vSettings;
Handler<HttpSettings> handler = remoteSettingsHandler;
if (handler != null) {
context.dispatch(vSettings, handler);
}
}
@Override
public Future<Void> shutdown(Duration timeout) {
if (timeout.isNegative()) {
throw new IllegalArgumentException("Timeout must be >= 0");
}
return connection.shutdown(timeout);
}
private void handleShutdown(QuicStreamChannel localControlStream, Duration timeout) {
localGoAway = mostRecentRemoteStreamId + 4;
PromiseInternal<Void> p = context.promise();
if (remoteGoAway == -1L) {
Handler<Void> handler = shutdownHandler;
if (handler != null) {
context.emit(null, handler);
}
}
sendGoAway(localControlStream, mostRecentRemoteStreamId + 4, p);
}
private void handleGrace(QuicStreamChannel localControlStream) {
if (localGoAway == -1L || localGoAway > 0L) {View on GitHub (pinned to fb308bd8c3)
Solutions
- Pass a zero or positive Duration, e.g. Duration.ZERO or Duration.ofSeconds(30).
- Clamp: Duration t = timeout.isNegative() ? Duration.ZERO : timeout.
- Use a null or a dedicated method if the API offers one for indefinite shutdown, instead of a negative sentinel.
Example fix
// before conn.shutdown(Duration.ofSeconds(-1)); // after conn.shutdown(Duration.ofSeconds(30));
Defensive patterns
Strategy: validation
Validate before calling
if (timeout == null || timeout.isNegative()) throw new IllegalArgumentException("timeout must be >= 0"); Type guard
boolean isValidShutdownTimeout(Duration d) { return d != null && !d.isNegative(); } Try / catch
try { conn.shutdown(timeout); } catch (IllegalArgumentException e) { conn.shutdown(Duration.ofSeconds(30)); } Prevention
- Map '-1 means infinite' configs to Duration.ZERO or a large positive duration
- Validate durations at config load time
- Use java.time.Duration factories, not manual arithmetic
- Check subtraction results for negative Durations
When it happens
Trigger: Calling shutdown(Duration.ofSeconds(-1)) or any negative duration, e.g. from misparsed configuration ('-1' meaning infinite) or an arithmetic result that went negative.
Common situations: Using -1 as an 'infinite/disabled' sentinel from other frameworks' conventions; subtracting deadlines producing negative Durations; config placeholders not replaced (e.g. ${timeout} parsed badly).
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.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- SSL configuration is necessary for a QUIC server
- Only TLSv1.3 supported
- http3MaxPoolSize must be > 0
- Invalid resolver idle timeout
- Server already bound
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/37187c4ce4269414.
Report an issue: GitHub.