apache/seatunnel · error · IOException

Failed to close Pulsar client after aborting transactions.

Error message

Failed to close Pulsar client after aborting transactions.

What it means

PulsarSinkCommitter.abort aborts active transactions and then closes the Pulsar client; if client.close() throws, it is wrapped in this IOException so the caller sees that the client failed to close after transaction abort. The transactions themselves were already aborted; this is a cleanup failure.

Source

Thrown at seatunnel-connectors-v2/connector-pulsar/src/main/java/org/apache/seatunnel/connectors/seatunnel/pulsar/sink/PulsarSinkCommitter.java:73

        }
        return commitInfos;
    }

    @Override
    public void abort(List<PulsarCommitInfo> commitInfos) throws IOException {
        if (commitInfos.isEmpty()) {
            return;
        }
        TransactionCoordinatorClient client = transactionCoordinatorClient();
        for (PulsarCommitInfo commitInfo : commitInfos) {
            TxnID txnID = commitInfo.getTxnID();
            client.abort(txnID);
        }
        if (this.pulsarClient != null) {
            try {
                PulsarConfigUtil.runWithConnectorClassLoader(pulsarClient::close);
            } catch (Exception e) {
                throw new IOException(
                        "Failed to close Pulsar client after aborting transactions.", e);
            }
        }
    }

    private TransactionCoordinatorClient transactionCoordinatorClient()
            throws PulsarClientException {
        if (coordinatorClient == null) {
            this.pulsarClient =
                    PulsarConfigUtil.createClient(clientConfig, PulsarSemantics.EXACTLY_ONCE);
            this.coordinatorClient = PulsarConfigUtil.getTcClient(pulsarClient);
        }
        return coordinatorClient;
    }
}

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Inspect the wrapped cause (e) for the real client close failure (broker connectivity, timeouts)
  2. Verify broker availability and network from the worker running the committer
  3. Ensure the client is not closed twice in custom code paths; retry the job if the abort itself succeeded
Defensive patterns

Strategy: try-catch

Try / catch

try {
  committer.abort(txn);
} catch (IOException e) {
  // abort() succeeded for transactions but client close failed; inspect e.getCause()
  LOG.warn("Client close failed after txn abort: {}", e.getCause(), e);
}

Prevention

When it happens

Trigger: abort(txn) is called, all transactions abort successfully, then pulsarClient.close() (run under the connector classloader) throws an Exception.

Common situations: Broker unreachable during close; classloader/shade issues with the Pulsar client; connection already torn down by the engine.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/e6e67d671816e9aa. Report an issue: GitHub.