apache/pulsar · error · org.apache.pulsar.client.impl.v5.PulsarClientException

${cause}

Error message

${cause}

What it means

Same wrapping pattern as the close failure family: close() blocks on closeAsync().get() and when the future fails it rethrows `new PulsarClientException(e.getCause())`, so `${cause}` is the underlying close failure (broker error, segment consumer close failure, network problem).

Source

Thrown at pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/ScalableQueueConsumer.java:268

        if (future != null) {
            future.thenAccept(c -> c.negativeAcknowledge(id.v4MessageId()));
        }
    }

    @Override
    public AsyncQueueConsumer<T> async() {
        return asyncView;
    }

    @Override
    public void close() throws PulsarClientException {
        try {
            closeAsync().get();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new PulsarClientException("Close interrupted", e);
        } catch (ExecutionException e) {
            throw new PulsarClientException(e.getCause());
        }
    }

    // --- Async internals ---

    @Override
    public CompletableFuture<Message<T>> receiveAsync() {
        return receiveQueue.receiveAsync();
    }

    @Override
    public CompletableFuture<Void> closeAsync() {
        closed = true;
        receiveQueue.close();
        dagWatch.close();

        List<CompletableFuture<Void>> futures = new ArrayList<>();
        for (var future : segmentConsumers.values()) {

View on GitHub (pinned to 820761864e)

Solutions

  1. Read e.getCause() to identify the actual failure
  2. Check broker health/connectivity and retry close on transient errors
  3. Ensure each segment's consumer can be closed (no in-flight transactions blocking close)
  4. Use closeAsync().exceptionally(...) to log per-segment failures explicitly

Example fix

// before
consumer.close();
// after
try {
    consumer.close();
} catch (PulsarClientException e) {
    Throwable cause = e.getCause();
    log.error("queue consumer close failed: {}", cause, cause);
}
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure broker reachable before close
if (!pulsarClient.getPartitionsForTopic(topic).isDone()) { /* wait */ }

Try / catch

try {
    consumer.close();
} catch (PulsarClientException e) {
    Throwable cause = e.getCause();
    log.error("close failed: {}", cause, cause);
    if (isTransient(cause)) retryClose(consumer);
}

Prevention

When it happens

Trigger: closeAsync() completing exceptionally during close(): segment consumer close rejected by broker, AlreadyClosed/ConsumerBusy errors, or connection loss while closing segments of the scalable queue.

Common situations: Closing while the broker is restarting; network partitions during application shutdown; closing consumers whose subscription is being deleted concurrently.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/15584a478928c18a. Report an issue: GitHub.