{"record":{"id":"7f58c06f65977104","repo":"apache/pulsar","slug":"wraps-commit-failure-cause-message","errorCode":null,"errorMessage":"(wraps commit failure cause message)","messagePattern":"\\(wraps commit failure cause message\\)","errorType":"exception","errorClass":"PulsarClientException","httpStatus":null,"severity":"error","filePath":"pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/TransactionV5.java","lineNumber":54,"sourceCode":"    TransactionV5(org.apache.pulsar.client.api.transaction.Transaction v4Transaction) {\n        this.v4Transaction = v4Transaction;\n        this.asyncView = new AsyncView();\n    }\n\n    org.apache.pulsar.client.api.transaction.Transaction v4Transaction() {\n        return v4Transaction;\n    }\n\n    @Override\n    public void commit() throws PulsarClientException {\n        try {\n            v4Transaction.commit().get();\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new PulsarClientException(\"Commit interrupted\", e);\n        } catch (ExecutionException e) {\n            Throwable cause = e.getCause() != null ? e.getCause() : e;\n            throw new PulsarClientException(cause.getMessage(), cause);\n        }\n    }\n\n    @Override\n    public void abort() throws PulsarClientException {\n        try {\n            v4Transaction.abort().get();\n        } catch (InterruptedException e) {\n            Thread.currentThread().interrupt();\n            throw new PulsarClientException(\"Abort interrupted\", e);\n        } catch (ExecutionException e) {\n            Throwable cause = e.getCause() != null ? e.getCause() : e;\n            throw new PulsarClientException(cause.getMessage(), cause);\n        }\n    }\n\n    @Override\n    public AsyncTransaction async() {","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-client-v5/src/main/java/org/apache/pulsar/client/impl/v5/TransactionV5.java#L36-L72","documentation":"TransactionV5.commit() blocks on the v4 transaction's commit future; when that future completes with ExecutionException, the cause is extracted (falling back to the ExecutionException itself if the cause is null) and rethrown as a PulsarClientException whose message is the underlying cause's message. This error therefore reports the broker/client's real reason the commit failed.","triggerScenarios":"Calling commit() when the underlying v4 commit future fails — broker rejected the commit, transaction timed out or was already aborted, coordinator unavailable, or the producer/consumer attached to the transaction errored.","commonSituations":"Transaction timeout exceeded (committing after the TTL); transaction coordinator restarted or unavailable; committing a transaction that another thread already aborted; broker-side authorization or ledger failures.","solutions":["Read the wrapped cause (getCause()) for the broker's actual rejection reason.","Commit within the transaction timeout — increase transactionTimeoutSeconds if operations take long.","Ensure only one thread commits/aborts the transaction; guard with ownership or serialization.","Check broker availability and transaction coordinator health; retry with a new transaction if the old one is definitively failed."],"exampleFix":"// before\ntxn.commit(); // may throw with opaque broker message\n// after\ntry {\n    txn.commit();\n} catch (PulsarClientException e) {\n    Throwable root = e.getCause() != null ? e.getCause() : e;\n    if (root instanceof TransactionInvalidException) {\n        startNewTransactionAndRetry();\n    } else {\n        throw e;\n    }\n}","handlingStrategy":"try-catch","validationCode":"if (txn == null || !txn.isOpen()) throw new IllegalStateException(\"transaction not open; cannot commit\");\nif (System.currentTimeMillis() - txnStartMillis > txnTimeoutMillis) log.warn(\"committing after timeout risk\");","typeGuard":"static boolean isCommitRejected(Throwable t) {\n    Throwable c = t;\n    while (c != null) { if (c.getMessage() != null && c.getMessage().contains(\"Transaction\")) return true; c = c.getCause(); }\n    return false;\n}","tryCatchPattern":"try {\n    txn.commit();\n} catch (PulsarClientException e) {\n    Throwable cause = e.getCause() != null ? e.getCause() : e;\n    log.error(\"commit failed: {}\", cause.getMessage(), cause);\n}","preventionTips":["Commit well within the configured transaction timeout","Single-thread ownership of commit/abort per transaction","Log the full cause chain, not just the wrapper message","Monitor broker transaction-coordinator health"],"tags":["transaction","commit","pulsar-client","wrapped-exception"],"backgroundTag":"transaction-commit-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"}