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.

Solutions

  1. Inspect the errorCode in the log to map to the driver/vendor XA error documentation
  2. Check for duplicate recovery processes rolling back the same xid concurrently
  3. 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

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


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

Appendix: 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)