apache/seatunnel · critical · JdbcConnectorException

CONNECT_DATABASE_FAILED

CONNECT_DATABASE_FAILED

Error message

open() failed.

What it means

JdbcInputFormat.open executes the split's generated SELECT statement (statement.executeQuery) and any SQLException aborts the reader with JdbcConnectorException CONNECT_DATABASE_FAILED. It first runs cleanupAfterOpenFailure to release the statement/resultSet, then fails the task. The thrown message appends the driver's SQLException text.

Solutions

  1. Check the wrapped SQLException message for the root cause (connection reset vs syntax vs permission)
  2. Verify the source table still exists and the configured user has SELECT privileges
  3. Test the same query manually with the JDBC driver against the database
  4. Check network stability/firewall idle timeouts; consider connection validation and reconnect settings
  5. If triggered during restore (testRestoreOnlyAssignReturnedSplits path), confirm checkpoint/restore data still matches the current table schema

Example fix

// before
url = "jdbc:mysql://db:3306/mydb" // user lacks SELECT on public.users
// after
GRANT SELECT ON mydb.public_users TO 'seatunnel'@'%';
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: verify connectivity and query before the job
try (Connection c = DriverManager.getConnection(url, user, pass);
     Statement s = c.createStatement()) {
    s.executeQuery("SELECT 1 FROM " + tablePath + " LIMIT 1");
}

Try / catch

try {
    source.open(split);
} catch (JdbcConnectorException e) {
    if (e.getErrorCode() == JdbcConnectorErrorCode.CONNECT_DATABASE_FAILED) {
        // retry with backoff after checking DB health
        retry(() -> source.open(split));
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Any SQLException while opening the split query: connection dropped after establishment, split statement generation produced invalid SQL (e.g. stale snapshot boundaries), insufficient privileges, or the referenced table/columns no longer exist.

Common situations: Database restarted or firewall dropped the idle connection between connection establishment and query execution, table dropped by another job between split enumeration and read, missing SELECT grant, dialect generating unsupported SQL for a specific split (e.g. limit/offset syntax).

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

Appendix: source

Thrown at seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/internal/JdbcInputFormat.java:121

    /**
     * Connects to the source database and executes the query
     *
     * @param inputSplit which is ignored if this InputFormat is executed as a non-parallel source,
     *     a "hook" to the query parameters otherwise (using its <i>parameterId</i>)
     * @throws IOException if there's an error during the execution of the query
     */
    public void open(JdbcSourceSplit inputSplit) throws IOException {
        try {
            splitTableSchema = tables.get(inputSplit.getTablePath()).getTableSchema();
            splitTableId = inputSplit.getTablePath().toString();

            statement = chunkSplitter.generateSplitStatement(inputSplit, splitTableSchema);
            resultSet = statement.executeQuery();
            hasNext = resultSet.next();
        } catch (SQLException se) {
            cleanupAfterOpenFailure(se);
            throw new JdbcConnectorException(
                    JdbcConnectorErrorCode.CONNECT_DATABASE_FAILED,
                    "open() failed." + se.getMessage(),
                    se);
        } catch (RuntimeException runtimeException) {
            cleanupAfterOpenFailure(runtimeException);
            throw runtimeException;
        }
    }

    private void cleanupAfterOpenFailure(Throwable openException) {
        boolean shouldDiscardConnection = statement == null;
        try {
            close();
        } catch (IOException cleanupException) {
            openException.addSuppressed(cleanupException);
            shouldDiscardConnection = true;
        } finally {
            if (shouldDiscardConnection) {

View on GitHub (pinned to cf67b549a7)