apache/seatunnel · warning

unable to close XA connection

Error message

unable to close XA connection

What it means

A WARN log in XaFacadeImplAutoLoad.close() when closing the underlying XA connection throws a SQLException. The resource is still discarded (xaResource nulled) even though the close failed; this is logged to flag a potential connection leak on the database side while not failing the job. Recovery: the connection object remains referenced by the JDBC driver until GC; some DBs may leak XA resources.

Solutions

  1. Verify network/firewall idle timeouts exceed checkpoint interval; enable TCP keepalive on the DB connection
  2. Check DB-side session limits and stale-connection cleanup (e.g. wait_timeout in MySQL)
  3. If leaks accumulate, restart the task or recycle the DataSource; this warning is otherwise safe to ignore at shutdown
  4. Upgrade the JDBC driver if a known close-after-XA bug applies
Defensive patterns

Strategy: try-catch

Validate before calling

// Before shutdown-sensitive jobs, verify DB connectivity
try (Connection c = dataSource.getConnection()) { /* healthy */ }

Try / catch

try {
    xaFacade.close();
} catch (Exception e) {
    // logged as 'unable to close XA connection'; non-fatal at shutdown
    LOG.warn("XA close failed, relying on DB-side cleanup/GC", e);
}

Prevention

When it happens

Trigger: close() attempts connection.close() on the physical XA connection and the driver throws SQLException — e.g. the network is already broken, the DB killed the session, or the driver already closed it (MySQL SuspendableXAConnection quirks).

Common situations: Job shutdown/recovery while the database connection is stale after long checkpoint intervals; MySQL connections pinned by XA; firewalled/idle connections dropped mid-run.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/64f36a4dabd10ce0. 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:138

    @Override
    public void close() throws SQLException {
        if (connection != null) {
            connection.close(); // close connection - likely a wrapper
            connection = null;
        }
        try {
            xaConnection.close(); // close likely a pooled AND the underlying connection
        } catch (SQLException e) {
            // Some databases (e.g. MySQL) rollback changes on normal client disconnect which
            // causes an exception if an XA transaction was prepared. Note that resources are
            // still released in case of an error. Pinning MySQL connections doesn't help as
            // SuspendableXAConnection has the same close() logic.
            // Other DBs don't rollback, e.g. for PgSql the previous connection.close() call
            // disassociates the connection (and that call works because it has a check for XA)
            // and rollback() is not called.
            // In either case, not closing the XA connection here leads to the resource leak.
            LOG.warn("unable to close XA connection", e);
        }
        xaResource = null;
    }

    @Override
    public Connection getConnection() {
        checkNotNull(connection);
        return connection;
    }

    @Override
    public boolean isConnectionValid() throws SQLException {
        return isOpen() && connection.isValid(connection.getNetworkTimeout());
    }

    @Override
    public Connection getOrEstablishConnection() throws SQLException {
        if (!isOpen()) {

View on GitHub (pinned to cf67b549a7)