apache/seatunnel · error · DebeziumException

Timed out after seconds while waiting to connect to MySQL…

Error message

Timed out after <actualSeconds> seconds while waiting to connect to MySQL at <hostname>:<port> with user '<username>'

What it means

The streaming source executes a JDBC connect to MySQL inside a loop that is expected to abort via InterruptedIOException/timeout when the configured connect timeout elapses. To distinguish a genuine network timeout from a too-short timeout or an interrupted connect, it measures elapsed wall-clock time: if the exception arrived only after >=90% of the timeout had really passed, it concludes the server was actually unreachable and throws this DebeziumException naming host, port, user, and measured seconds.

Solutions

  1. Verify network reachability from the connector host: `mysql -h <hostname> -P <port> -u <username> -p` or `nc -vz <hostname> <port>`.
  2. Increase the connect timeout option (e.g. `database.connection.timeout` / serverTimezone-compatible JDBC connectTimeout in the connector config) if the server is merely slow to accept connections.
  3. Check MySQL server state: is it running, is `max_connections` exhausted, are there firewall/security-group rules allowing the connector's IP?
  4. Fix hostname resolution (use the correct service DNS/IP; replace 'localhost' with the MySQL container/service name in containerized deployments).
  5. Confirm the account exists and is allowed from the connector's source host (`SHOW GRANTS FOR 'user'@'host'`) — though a plain auth refusal usually surfaces as a different error.

Example fix

// before: hostname unreachable from inside the job container
url = "jdbc:mysql://localhost:3306/orders"

// after: use the service-resolvable host and a longer timeout
url = "jdbc:mysql://mysql.database.svc.cluster.local:3306/orders?connectTimeout=60000"
Defensive patterns

Strategy: retry

Validate before calling

// preflight check before starting the streaming source
if (!pingMysql(host, port, timeoutMillis)) {
  throw new IllegalStateException("Cannot reach MySQL at " + host + ":" + port + " — fix network/credentials first");
}

Try / catch

try {
  startStreamingSource(config);
} catch (DebeziumException e) {
  if (e.getMessage().startsWith("Timed out after") && e.getMessage().contains("waiting to connect to MySQL")) {
    retryWithBackoff(() -> startStreamingSource(config), 3);
  } else throw e;
}

Prevention

When it happens

Trigger: JDBC connection attempts to connectorConfig.hostname():port keep failing/timing out until the cumulative elapsed time exceeds 0.9 * the configured connect timeout (database.connection.timeout / connection.timeout.ms), with user <username>; thrown from the MySqlStreamingChangeEventSource constructor.

Common situations: MySQL host unreachable or DNS misconfigured; firewall/security group blocking 3306; MySQL max_connections exhausted or server overloaded; wrong port or VPC/network peering missing; user account or host grants fine but network blackhole causes silent drop; containerized setups using 'localhost' from inside another container.

Understand the failure class

Related errors


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

Appendix: source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-mysql/src/main/java/io/debezium/connector/mysql/MySqlStreamingChangeEventSource.java:1220

                            for (Thread t : binaryLogClientThreads.values()) {
                                if (t.getName().startsWith(KEEPALIVE_THREAD_NAME) && t.isAlive()) {
                                    LOGGER.info("Keepalive thread is running");
                                    keepAliveThreadRunning = true;
                                }
                            }
                            metronome.pause();
                        }
                    }
                } catch (TimeoutException e) {
                    // If the client thread is interrupted *before* the client could connect, the
                    // client throws a timeout exception
                    // The only way we can distinguish this is if we get the timeout exception
                    // before the specified timeout has
                    // elapsed, so we simply check this (within 10%) ...
                    long duration = clock.currentTimeInMillis() - started;
                    if (duration > (0.9 * timeout)) {
                        double actualSeconds = TimeUnit.MILLISECONDS.toSeconds(duration);
                        throw new DebeziumException(
                                "Timed out after "
                                        + actualSeconds
                                        + " seconds while waiting to connect to MySQL at "
                                        + connectorConfig.hostname()
                                        + ":"
                                        + connectorConfig.port()
                                        + " with user '"
                                        + connectorConfig.username()
                                        + "'",
                                e);
                    }
                    // Otherwise, we were told to shutdown, so we don't care about the timeout
                    // exception
                } catch (AuthenticationException e) {
                    throw new DebeziumException(
                            "Failed to authenticate to the MySQL database at "
                                    + connectorConfig.hostname()
                                    + ":"

View on GitHub (pinned to cf67b549a7)