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

  1. Create the InboundBuffer only after a context exists: call vertx.getOrCreateContext() and pass the result
  2. Construct the InboundBuffer lazily inside the first read/handler call instead of in a constructor/field initializer
  3. 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

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


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/a537115b46a6b329. Report an issue: GitHub.