apache/seatunnel · error · JdbcConnectorException

COMMON_WRITER_OPERATION_FAILED

COMMON_WRITER_OPERATION_FAILED

Error message

unable to open JDBC sink committer

What it means

JdbcSinkCommitter's constructor opens an XA facade (XaFacade.fromJdbcConnectionOptions + xaFacade.open()) to manage exactly-once XA transactions; if opening the XA resource fails, it wraps the failure in WRITER_OPERATION_FAILED with message 'unable to open JDBC sink committer'. This means the committer could not establish a JDBC/XA connection to the database.

Source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSinkCommitter.java:47

import org.apache.seatunnel.connectors.seatunnel.jdbc.state.XidInfo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class JdbcSinkCommitter implements SinkCommitter<XidInfo> {
    private final XaFacade xaFacade;
    private final XaGroupOps xaGroupOps;
    private final JdbcConnectionConfig jdbcConnectionConfig;

    public JdbcSinkCommitter(JdbcSinkConfig jdbcSinkConfig) throws IOException {
        this.jdbcConnectionConfig = jdbcSinkConfig.getJdbcConnectionConfig();
        this.xaFacade = XaFacade.fromJdbcConnectionOptions(jdbcConnectionConfig);
        this.xaGroupOps = new XaGroupOpsImpl(xaFacade);
        try {
            xaFacade.open();
        } catch (Exception e) {
            throw new JdbcConnectorException(
                    CommonErrorCodeDeprecated.WRITER_OPERATION_FAILED,
                    "unable to open JDBC sink committer",
                    e);
        }
    }

    @Override
    public List<XidInfo> commit(List<XidInfo> committables) {
        return xaGroupOps
                .commit(
                        new ArrayList<>(committables),
                        false,
                        jdbcConnectionConfig.getMaxCommitAttempts())
                .getForRetry();
    }

    @Override
    public void abort(List<XidInfo> commitInfos) {

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Read the wrapped cause 'e' in the logs — it names the actual failure (connection refused, auth failed, unknown driver)
  2. Verify network connectivity and credentials from the SeaTunnel worker node to the database
  3. Confirm the JDBC driver jar is installed under connectors/ and the url/driver options are correct
  4. If the DB was temporarily down, simply retry the job once connectivity is restored

Example fix

// before
url = "jdbc:mysql://localhost:3306/db"
// after
url = "jdbc:mysql://db-host.internal:3306/db?useServerPrepStmts=true&connectTimeout=5000"
Defensive patterns

Strategy: retry

Validate before calling

try (Connection c = DriverManager.getConnection(jdbcUrl, user, pass)) {
  // connectivity + credentials check before submitting the job
  c.isValid(5);
}

Try / catch

try {
  xaFacade.open();
} catch (JdbcConnectorException e) {
  logger.error("failed to open committer, cause: {}", e.getCause(), e);
  // retry with backoff or surface the root cause to the operator
}

Prevention

When it happens

Trigger: Constructing JdbcSinkCommitter during sink commit phase when the underlying connection cannot be opened: bad JDBC URL, unreachable host/port, wrong credentials, driver missing, or the database not supporting the requested XA datasource.

Common situations: Database restarted or network partitioned between write and commit phases; expired/rotated DB credentials; misconfigured URL in jdbc connection options; driver jar not present in the plugin directory when the committer is instantiated.

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/c738d5dfee946f4d. Report an issue: GitHub.