eclipse-vertx/vert.x · error · IllegalArgumentException
highWaterMark
Error message
highWaterMark
What it means
InboundBuffer's constructor validates that the high-water mark used for back-pressure is non-negative. Passing a negative value throws IllegalArgumentException with the configured value, because a negative threshold makes the writable/overflow semantics of the buffer meaningless.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/streams/impl/InboundBuffer.java:92
private final long highWaterMark;
private long demand;
private Handler<E> handler;
private boolean overflow;
private Handler<Void> drainHandler;
private Handler<Void> emptyHandler;
private Handler<Throwable> exceptionHandler;
private boolean emitting;
public InboundBuffer(Context context) {
this(context, 16L);
}
public InboundBuffer(Context context, long highWaterMark) {
if (context == null) {
throw new NullPointerException("context must not be null");
}
if (highWaterMark < 0) {
throw new IllegalArgumentException("highWaterMark " + highWaterMark + " >= 0");
}
this.context = (ContextInternal) context;
this.highWaterMark = highWaterMark;
this.demand = Long.MAX_VALUE;
// empty ArrayDeque's constructor ArrayDeque allocates 16 elements; let's delay the allocation to be of the proper size
this.pending = null;
}
private void checkThread() {
if (!context.inThread()) {
throw new IllegalStateException("This operation must be called from a Vert.x thread");
}
}
/**
* Write an {@code element} to the buffer. The element will be delivered synchronously to the handler when
* it is possible, otherwise it will be queued for later delivery.
*View on GitHub (pinned to fb308bd8c3)
Solutions
- Pass a positive (or zero) highWaterMark; use Long.MAX_VALUE if unbounded delivery is intended
- Clamp the configured value before constructing: Math.max(0, configuredValue)
- Fix the config source that supplies the -1 sentinel and parse it into a valid positive value
Example fix
// before long hwm = config.getBufferLimit(); // may be -1 InboundBuffer buf = new InboundBuffer(context, hwm); // after long hwm = config.getBufferLimit(); InboundBuffer buf = new InboundBuffer(context, hwm < 0 ? Long.MAX_VALUE : hwm);
Defensive patterns
Strategy: validation
Validate before calling
long hwm = configuredHighWaterMark; if (hwm < 0) hwm = Long.MAX_VALUE; // unbounded new InboundBuffer(context, hwm);
Prevention
- Treat -1 sentinels explicitly before constructing
- Clamp config-driven sizes with Math.max(0, value)
- Document that highWaterMark must be >= 0
When it happens
Trigger: new InboundBuffer(context, highWaterMark) with a negative long, e.g. setHighWaterMark(-1) in ReadStream options or a computed value from a misparsed config (size = -1 meaning 'unlimited' by some external convention).
Common situations: Using -1 as a sentinel for 'no limit' copied from another library; config values parsed with a default of -1; arithmetic underflow when computing buffer sizes.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- maxPoolSize must be > 0
- http2MaxPoolSize must be > 0
- http3MaxPoolSize must be > 0
- maxLifetime must be >= 0
- maxSize must be > 0
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/31cf55bcd17da2d9.
Report an issue: GitHub.