apache/seatunnel · error · IllegalStateException
The DB connection is not a valid replication connection
Error message
The DB connection is not a valid replication connection
What it means
Raised during initReplicationSlot after executing IDENTIFY_SYSTEM on the replication connection. IDENTIFY_SYSTEM must return exactly one row containing the current xlogpos; an empty result set means the JDBC connection, although opened with replication=database, is not actually a valid physical replication connection. The library throws IllegalStateException because this is an internal invariant violation.
Source
Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-opengauss/src/main/java/io/debezium/connector/postgresql/connection/PostgresReplicationConnection.java:330
// there's no info for this plugin and slot so create a new slot
if (shouldCreateSlot) {
this.createReplicationSlot();
}
// replication connection does not support parsing of SQL statements so we need to
// create
// the connection without executing on connect statements - see JDBC opt
// preferQueryMode=simple
pgConnection();
final String identifySystemStatement = "IDENTIFY_SYSTEM";
LOGGER.debug(
"running '{}' to validate replication connection", identifySystemStatement);
final Lsn xlogStart =
queryAndMap(
identifySystemStatement,
rs -> {
if (!rs.next()) {
throw new IllegalStateException(
"The DB connection is not a valid replication connection");
}
String xlogpos = rs.getString("xlogpos");
LOGGER.debug("received latest xlogpos '{}'", xlogpos);
return Lsn.valueOf(xlogpos);
});
if (slotCreationInfo != null) {
this.defaultStartingPos = slotCreationInfo.startLsn();
} else if (shouldCreateSlot || !slotInfo.hasValidFlushedLsn()) {
// this is a new slot or we weren't able to read a valid flush LSN pos, so we always
// start from the xlog pos that was reported
this.defaultStartingPos = xlogStart;
} else {
Lsn latestFlushedLsn = slotInfo.latestFlushedLsn();
this.defaultStartingPos =
latestFlushedLsn.compareTo(xlogStart) < 0 ? latestFlushedLsn : xlogStart;
if (LOGGER.isDebugEnabled()) {View on GitHub (pinned to cf67b549a7)
Solutions
- Check the replication connection URL includes the replication=database parameter and the correct user with REPLICATION privilege.
- Bypass connection poolers/proxies (PgBouncer transaction pooling) and connect directly to the primary server for the streaming connection.
- Verify the target is a genuine PostgreSQL/openGauss primary: run `psql "replication=database" -c IDENTIFY_SYSTEM` manually with the same credentials.
- Confirm the PostgreSQL JDBC driver version matches what the connector expects; upgrade the connector/driver if the replication parameter is being dropped.
- Ensure you connect to the primary, not a hot standby without appropriate settings, and that wal_level=logical where required.
Example fix
// before (misconfigured URL, no replication mode) String url = "jdbc:postgresql://host:5432/mydb"; // after String url = "jdbc:postgresql://host:5432/mydb?replication=database";
Defensive patterns
Strategy: validation
Validate before calling
// validate replication capability before starting the connector
try (Connection c = DriverManager.getConnection(
"jdbc:postgresql://host:5432/mydb?replication=database", user, pass);
Statement s = c.createStatement();
ResultSet rs = s.executeQuery("IDENTIFY_SYSTEM")) {
if (!rs.next()) throw new IllegalStateException("endpoint is not a valid replication connection");
System.out.println("xlogpos=" + rs.getString("xlogpos"));
} Try / catch
try {
engine.start();
} catch (IllegalStateException e) {
if (e.getMessage().contains("not a valid replication connection")) {
// fix JDBC URL / bypass pooler / check REPLICATION privilege, then retry
} else {
throw e;
}
} Prevention
- Always include replication=database in the streaming connection URL.
- Never route replication connections through PgBouncer or transaction-mode poolers.
- Grant REPLICATION (or rds_replication on RDS) to the connector user.
- Smoke-test with `psql "replication=database" -c IDENTIFY_SYSTEM` before deploying.
When it happens
Trigger: The connection URL used for streaming does not include replication=database (or an equivalent replication mode), the driver silently downgraded the connection, or the server accepted the connection but the IDENTIFY_SYSTEM result set came back empty (non-Postgres/openGauss compatible endpoint).
Common situations: Misconfigured JDBC URL parameters in connector config (missing replication=true/database param); connecting through a proxy or pooler (e.g. PgBouncer in transaction mode) that strips replication capabilities; pointing the connector at a non-PostgreSQL-compatible database that pretends to speak the wire protocol; driver version mismatch overriding replication mode.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
- Failed to discover remaining tables to capture
- Error to check tables:
- Failed to disable auto commit for Db2 CDC connection
- Couldn't get timestamp utils from underlying connection
- Unable to %s filtered publication %s for %s
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/0dc897571dc04dc9.
Report an issue: GitHub.