apache/kafka · error · IllegalArgumentException

The exception passed to raise must not be null

Error message

The exception passed to raise must not be null

What it means

Thrown by RequestFuture.raise(RuntimeException e) when e is null. The future stores the exception directly as its result and later returns it from exception(); a null result would alias INCOMPLETE_SENTINEL-style bugs and make failed()/exception() inconsistent. raise() therefore requires a non-null RuntimeException so the failure state is always observable.

Source

Thrown at clients/src/main/java/org/apache/kafka/clients/consumer/internals/RequestFuture.java:144

            if (!result.compareAndSet(INCOMPLETE_SENTINEL, value))
                throw new IllegalStateException("Invalid attempt to complete a request future which is already complete");
            fireSuccess();
        } finally {
            completedLatch.countDown();
        }
    }

    /**
     * Raise an exception. The request will be marked as failed, and the caller can either
     * handle the exception or throw it.
     * @param e corresponding exception to be passed to caller
     * @throws IllegalStateException if the future has already been completed
     */
    public void raise(RuntimeException e) {
        try {
            if (e == null)
                throw new IllegalArgumentException("The exception passed to raise must not be null");

            if (!result.compareAndSet(INCOMPLETE_SENTINEL, e))
                throw new IllegalStateException("Invalid attempt to complete a request future which is already complete");

            fireFailure();
        } finally {
            completedLatch.countDown();
        }
    }

    /**
     * Raise an error. The request will be marked as failed.
     * @param error corresponding error to be passed to caller
     */
    public void raise(Errors error) {
        raise(error.exception());
    }

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Ensure the exception passed to raise() is non-null; guard with if (e != null) future.raise(e).
  2. If translating from org.apache.kafka.common.protocol.Errors, use future.raise(error) (the Errors overload) which never produces null.
  3. Replace null failure causes with an explicit IllegalStateException("unknown failure") so the failure is observable.

Example fix

// before
RuntimeException e = lookupException(code); // may return null
future.raise(e); // throws if e == null

// after
RuntimeException e = lookupException(code);
future.raise(e != null ? e : new IllegalStateException("unknown error code " + code));
Defensive patterns

Strategy: validation

Validate before calling

// Before calling raise(e), ensure the exception is non-null.
if (e == null) {
    throw new IllegalArgumentException("raise() requires a non-null exception");
}
future.raise(e);
// Or use the Errors overload which cannot be null: future.raise(Errors.XXX);

Type guard

java.util.function.BiConsumer<RequestFuture<?>, RuntimeException> safeRaise = (f, e) -> {
    if (e == null) {
        throw new IllegalArgumentException("exception must not be null");
    }
    f.raise(e);
};

Try / catch

try {
    future.raise(e);
} catch (IllegalArgumentException ex) {
    // e was null; supply a concrete failure
    future.raise(new org.apache.kafka.common.errors.UnknownServerException());
}

Prevention

When it happens

Trigger: Calling future.raise(null); passing the result of a method that can return null (e.g. some Errors.exception() variants or a lookup that returned null) without a null check; calling raise(error.exception()) where error is null.

Common situations: Static analysis or refactors that surface a previously-unreachable null path; helper methods that translate Errors into exceptions returning null for an unknown code; defensive code that catches Throwable and passes the (possibly null) cause into raise().

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/50e2781766406e30.json. Report an issue: GitHub.