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).
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)
Solutions
- Read the wrapped cause's message for the real failure (coordinator unavailable, client closed, timeout)
- Ensure the broker has transactions enabled (transactionCoordinatorEnabled=true) and is reachable
- 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
- Verify the broker has transactions enabled (transactionCoordinatorEnabled=true) before using transactions
- Check the client is open before creating transactions
- Prefer newTransactionAsync() in async code to avoid blocking/unwrapping
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
- This Broker is not configured with transactionCoordinatorEna
- PublishTxnMessage is not supported by non-persistent topic
- Cannot start the service once it was stopped
- webServicePort/webServicePortTls or http/https bindAddresses
- The retention size must > the backlog quota limit size, but
AI-assisted analysis of apache/pulsar@820761864e (2026-09-06).
Data as JSON: /api/errors/f1bb52bae7df0397.
Report an issue: GitHub.