apache/seatunnel · warning
formatErrorMessage(action, xid, errorCode, errorMessage)
Error message
formatErrorMessage(action, xid, errorCode, errorMessage)
What it means
A WARN log produced by formatErrorMessage(...) in XaFacadeImplAutoLoad.failAndRollback(). When ending a transaction in fail mode (end+rollback for a prepared-but-uncommitted XA transaction) fails with an XAException whose code is below XA_RBBASE (i.e. not a rollback-related code), the facade logs a formatted message with the action, xid and error code instead of retrying rollback. The transaction's fate depends on the recovery mechanism.
Source
Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/xa/XaFacadeImplAutoLoad.java:212
formatErrorMessage("prepare", of(xid), empty(), "response: " + prepResult));
}
}
@Override
public void failAndRollback(Xid xid) {
execute(
Command.fromRunnable(
"end (fail)",
xid,
() -> {
xaResource.end(xid, XAResource.TMFAIL);
xaResource.rollback(xid);
},
err -> {
if (err.errorCode >= XA_RBBASE) {
rollback(xid);
} else {
LOG.warn(
formatErrorMessage(
"end (fail)", of(xid), of(err.errorCode)));
}
}));
}
@Override
public void commit(Xid xid, boolean ignoreUnknown) {
execute(
Command.fromRunnableRecoverByWarn(
"commit",
xid,
() ->
xaResource.commit(
xid,
false /* not onePhase because the transaction should be prepared already */),
e -> buildCommitErrorDesc(e, ignoreUnknown)));
}View on GitHub (pinned to cf67b549a7)
Solutions
- Inspect the errorCode in the log to map to the driver/vendor XA error documentation
- Check for duplicate recovery processes rolling back the same xid concurrently
- Verify the DB's XA support and driver compatibility; retry the job or run XA recovery (xa_recover) manually if in-doubt transactions accumulate
Defensive patterns
Strategy: retry
Validate before calling
// Ensure no concurrent recovery processes operate on the same xid namespace // and the DB user has XA privileges: // GRANT XA_RECOVER_ADMIN ON *.* TO 'user'@'host'; -- MySQL
Try / catch
// XAException handling in user code if replicating abort logic:
try {
xaResource.end(xid, XAResource.TMFAIL);
xaResource.rollback(xid);
} catch (XAException e) {
if (e.errorCode >= XAException.XA_RBBASE) {
xaResource.rollback(xid);
} else {
LOG.warn("end(fail) failed, errorCode=" + e.errorCode + ", xid=" + xid);
}
} Prevention
- Avoid running two recovery processes with the same transaction prefix
- Map the logged errorCode to vendor XA documentation
- Ensure stable network to the DB during checkpoint abort paths
When it happens
Trigger: failAndRollback(xid) executes end(fail)+rollback asynchronously; the XAException error code is unexpected (< XA_RBBASE), so rollback is skipped and only a formatted warning (action, xid, errorCode) is emitted.
Common situations: Transaction already committed/rolled back elsewhere (recovery race); XA protocol violation from the driver; resource manager temporarily unavailable during abort path.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- XA_OPERATION_FAILED
- XA_OPERATION_FAILED
- unable to fail/rollback transaction, xid={}: {}
- rollback {} recovered transactions
- CLASS_NOT_FOUND
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/6a8b251f15a66fbd.
Report an issue: GitHub.