eclipse-vertx/vert.x · error · NullPointerException
context must not be null
Error message
context must not be null
What it means
InboundBuffer is Vert.x's internal buffering queue for ReadStream implementations; it requires a Vert.x context to run handlers on. The constructor throws NullPointerException immediately when passed a null Context, since all buffering, demand accounting, and handler delivery depend on it.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/streams/impl/InboundBuffer.java:89
private final ContextInternal context;
private ArrayDeque<E> pending;
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");
}
}
/**View on GitHub (pinned to fb308bd8c3)
Solutions
- Create the InboundBuffer only after a context exists: call vertx.getOrCreateContext() and pass the result
- Construct the InboundBuffer lazily inside the first read/handler call instead of in a constructor/field initializer
- Pass the ContextInternal captured during stream init (as core ReadStream impls do)
Example fix
// before this.inboundBuffer = new InboundBuffer(null); // after ContextInternal ctx = (ContextInternal) vertx.getOrCreateContext(); this.inboundBuffer = new InboundBuffer(ctx);
Defensive patterns
Strategy: validation
Validate before calling
if (context == null) {
context = vertx.getOrCreateContext();
}
InboundBuffer buf = new InboundBuffer(context); Type guard
boolean hasContext(Context c) { return c != null; } Try / catch
try {
new InboundBuffer(ctx);
} catch (NullPointerException e) {
// create context and retry
} Prevention
- Construct InboundBuffer lazily, after the stream is attached to a context
- Use vertx.getOrCreateContext() at construction sites
- Never create Vert.x stream machinery in plain static initializers
When it happens
Trigger: Passing null as the Context argument to new InboundBuffer(context) or new InboundBuffer(context, highWaterMark) — typically inside a custom ReadStream implementation that has no attached context (e.g. constructed outside vertx.getOrCreateContext() or before deployment).
Common situations: Writing a custom ReadStream and creating the InboundBuffer in a field initializer or plain constructor where no Vert.x context exists yet; using Vert.x objects created with Vertx.vertexContext() absent (embedded/standalone usage).
Related errors
- No null bind local address
- Invalid null value passed for traffic shaping options update
- This operation must be called from a Vert.x thread
- blockedThreadCheckInterval must be > 0
- maxEventLoopExecuteTime must be > 0
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/a537115b46a6b329.
Report an issue: GitHub.