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

${cause.getMessage()}

Error message

${cause.getMessage()}

What it means

The synchronous newTransaction() waits on newTransactionAsync().get(); if the async transaction-creation completes exceptionally, the ExecutionException is unwrapped and its cause is re-thrown as a PulsarClientException carrying the underlying message. The dynamic message reflects whatever actually went wrong on the broker/client during transaction creation (e.g. transaction coordinator unavailable, client closed).

Solutions

  1. Read the wrapped cause's message for the real failure (coordinator unavailable, client closed, timeout)
  2. Ensure the broker has transactions enabled (transactionCoordinatorEnabled=true) and is reachable
  3. Verify the client is not already closed and retry transaction creation
Defensive patterns

Strategy: try-catch

Try / catch

try {
    Transaction tx = client.newTransaction();
} catch (PulsarClientException e) {
    log.error("Transaction creation failed: {}", e.getMessage(), e.getCause());
}

Prevention

When it happens

Trigger: Calling PulsarClientV5.newTransaction() when the underlying v4 client's async transaction creation fails — broker has no transaction coordinator assigned, transactions are disabled in broker config, or the client was already closed.

Common situations: Enabling transactional producers on a broker where transactionCoordinatorEnabled=false; hitting a broker that does not support the transaction API; calling newTransaction() after close(); timeouts waiting for a coordinator.

Related errors


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

Appendix: source

Thrown at pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/PulsarClientV5.java:85

    }

    @Override
    public <T> QueueConsumerBuilder<T> newQueueConsumer(Schema<T> schema) {
        return new QueueConsumerBuilderV5<>(this, schema);
    }

    @Override
    public <T> CheckpointConsumerBuilder<T> newCheckpointConsumer(Schema<T> schema) {
        return new CheckpointConsumerBuilderV5<>(this, schema);
    }

    @Override
    public Transaction newTransaction() throws PulsarClientException {
        try {
            return newTransactionAsync().get();
        } catch (ExecutionException e) {
            Throwable cause = e.getCause() != null ? e.getCause() : e;
            throw new PulsarClientException(cause.getMessage(), cause);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new PulsarClientException("Interrupted while creating transaction", e);
        }
    }

    @Override
    public CompletableFuture<Transaction> newTransactionAsync() {
        var builder = v4Client.newTransaction();
        if (transactionTimeout != null) {
            builder.withTransactionTimeout(transactionTimeout.toMillis(), TimeUnit.MILLISECONDS);
        }
        return builder.build().thenApply(v4Txn -> (Transaction) new TransactionV5(v4Txn));
    }

    @Override
    public void close() throws PulsarClientException {
        try {

View on GitHub (pinned to 820761864e)