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

Interrupted while creating transaction

Error message

Interrupted while creating transaction

What it means

newTransaction() blocks on the async future; if the calling thread is interrupted while waiting, an InterruptedException is caught, the interrupt flag is restored via Thread.currentThread().interrupt(), and a PulsarClientException with the fixed message 'Interrupted while creating transaction' is thrown. The error means the caller (or a shutdown path) interrupted the thread, not that the broker rejected the transaction.

Source

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

    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 {
            v4Client.close();
        } catch (org.apache.pulsar.client.api.PulsarClientException e) {
            throw new PulsarClientException(e.getMessage(), e);

View on GitHub (pinned to 820761864e)

Solutions

  1. Check who interrupted the thread — usually a shutdown or timeout mechanism — and decide whether transaction creation should be allowed to finish
  2. Preserve/respect the interrupt: the library already re-sets the interrupt flag; avoid swallowing it in your own code
  3. Avoid calling blocking newTransaction() from threads subject to interruption; prefer newTransactionAsync() and handle completion asynchronously

Example fix

// before
Transaction tx = client.newTransaction(); // blocking, interruptible
// after
Transaction tx = client.newTransactionAsync()
    .orTimeout(30, TimeUnit.SECONDS)
    .join();
Defensive patterns

Strategy: try-catch

Try / catch

try {
    Transaction tx = client.newTransaction();
} catch (PulsarClientException e) {
    if (Thread.currentThread().isInterrupted()) {
        log.warn("Transaction creation interrupted; aborting");
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: A thread calling newTransaction() is interrupted while blocked in newTransactionAsync().get() — typically from an executor shutdownNow(), a timeout mechanism that interrupts workers, or application shutdown.

Common situations: Cancelling in-flight work via ExecutorService.shutdownNow(); framework code interrupting request-handling threads on request timeout; JVM shutdown hooks interrupting client threads.

Related errors


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