{"record":{"id":"15584a478928c18a","repo":"apache/pulsar","slug":"cause-15584a","errorCode":null,"errorMessage":"${cause}","messagePattern":"\\$\\{cause\\}","errorType":"exception","errorClass":"org.apache.pulsar.client.impl.v5.PulsarClientException","httpStatus":null,"severity":"error","filePath":"pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/ScalableQueueConsumer.java","lineNumber":268,"sourceCode":"        if (future != null) {\n            future.thenAccept(c -> c.negativeAcknowledge(id.v4MessageId()));\n        }\n    }\n\n    @Override\n    public AsyncQueueConsumer<T> async() {\n        return asyncView;\n    }\n\n    @Override\n    public void close() throws PulsarClientException {\n        try {\n            closeAsync().get();\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new PulsarClientException(\"Close interrupted\", e);\n        } catch (ExecutionException e) {\n            throw new PulsarClientException(e.getCause());\n        }\n    }\n\n    // --- Async internals ---\n\n    @Override\n    public CompletableFuture<Message<T>> receiveAsync() {\n        return receiveQueue.receiveAsync();\n    }\n\n    @Override\n    public CompletableFuture<Void> closeAsync() {\n        closed = true;\n        receiveQueue.close();\n        dagWatch.close();\n\n        List<CompletableFuture<Void>> futures = new ArrayList<>();\n        for (var future : segmentConsumers.values()) {","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/ScalableQueueConsumer.java#L250-L286","documentation":"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).","triggerScenarios":"closeAsync() completing exceptionally during close(): segment consumer close rejected by broker, AlreadyClosed/ConsumerBusy errors, or connection loss while closing segments of the scalable queue.","commonSituations":"Closing while the broker is restarting; network partitions during application shutdown; closing consumers whose subscription is being deleted concurrently.","solutions":["Read e.getCause() to identify the actual failure","Check broker health/connectivity and retry close on transient errors","Ensure each segment's consumer can be closed (no in-flight transactions blocking close)","Use closeAsync().exceptionally(...) to log per-segment failures explicitly"],"exampleFix":"// before\nconsumer.close();\n// after\ntry {\n    consumer.close();\n} catch (PulsarClientException e) {\n    Throwable cause = e.getCause();\n    log.error(\"queue consumer close failed: {}\", cause, cause);\n}","handlingStrategy":"try-catch","validationCode":"// ensure broker reachable before close\nif (!pulsarClient.getPartitionsForTopic(topic).isDone()) { /* wait */ }","typeGuard":null,"tryCatchPattern":"try {\n    consumer.close();\n} catch (PulsarClientException e) {\n    Throwable cause = e.getCause();\n    log.error(\"close failed: {}\", cause, cause);\n    if (isTransient(cause)) retryClose(consumer);\n}","preventionTips":["Close during stable connectivity windows","Retry close on transient network errors","Avoid concurrent close/delete of the subscription","Use closeAsync() to observe per-segment failures"],"tags":["pulsar","close","lifecycle","network"],"backgroundTag":"consumer-close-failed","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}