apache/shardingsphere · error · PipelineInternalException
Unsupported PostgreSQL version: %s
Error message
Unsupported PostgreSQL version: %s
What it means
The PostgreSQL incremental position manager needs the current WAL LSN to seed incremental ingestion. It picks a SQL function by server version: PG_CURRENT_XLOG_LOCATION for 9.6 and PG_CURRENT_WAL_LSN for 10+. Any older server (or a version metadata report it cannot classify) triggers a PipelineInternalException naming the exact product version string.
Source
Thrown at kernel/data-pipeline/dialect/postgresql/src/main/java/org/apache/shardingsphere/data/pipeline/postgresql/ingest/incremental/wal/position/PostgreSQLIncrementalPositionManager.java:70
}
private WALPosition getWALPosition(final Connection connection, final String logSequenceNumberSQL) throws SQLException {
try (
PreparedStatement preparedStatement = connection.prepareStatement(logSequenceNumberSQL);
ResultSet resultSet = preparedStatement.executeQuery()) {
resultSet.next();
return new WALPosition(new PostgreSQLLogSequenceNumber(LogSequenceNumber.valueOf(resultSet.getString(1))));
}
}
private String getLogSequenceNumberSQL(final DatabaseMetaData metaData) throws SQLException {
if (9 == metaData.getDatabaseMajorVersion() && 6 <= metaData.getDatabaseMinorVersion()) {
return "SELECT PG_CURRENT_XLOG_LOCATION()";
}
if (10 <= metaData.getDatabaseMajorVersion()) {
return "SELECT PG_CURRENT_WAL_LSN()";
}
throw new PipelineInternalException("Unsupported PostgreSQL version: " + metaData.getDatabaseProductVersion());
}
@Override
public void destroy(final DataSource dataSource, final String slotNameSuffix) throws SQLException {
try (Connection connection = dataSource.getConnection()) {
slotManager.dropIfExisted(connection, slotNameSuffix);
}
}
@Override
public String getDatabaseType() {
return "PostgreSQL";
}
}
View on GitHub (pinned to e952770a21)
Solutions
- Use PostgreSQL 9.6+ (ideally 10+) as the pipeline source; upgrade the source server.
- Verify the actual server behind the JDBC URL with SELECT version(); a proxy or pgbouncer routing may point at an older instance than intended.
- If stuck on an old version in a fork, extend getLogSequenceNumberSQL to handle its version and LSN function, but this requires a code change and is unsupported upstream.
Defensive patterns
Strategy: validation
Validate before calling
try (Connection conn = dataSource.getConnection()) {
DatabaseMetaData md = conn.getMetaData();
int major = md.getDatabaseMajorVersion(), minor = md.getDatabaseMinorVersion();
if (major < 9 || (9 == major && minor < 6)) {
throw new IllegalStateException("PostgreSQL 9.6+ required, got " + md.getDatabaseProductVersion());
}
} Try / catch
try {
position = positionManager.getPosition(dataSource);
} catch (final PipelineInternalException ex) {
// surface version string and abort job setup before slot creation
throw ex;
} Prevention
- Assert source PostgreSQL version >= 9.6 in deployment checks.
- Verify SELECT version() on the exact host the JDBC URL resolves to.
- Beware connection routers/proxies that change which server is reached.
When it happens
Trigger: Calling getPosition(...) on a PostgreSQL connection whose DatabaseMetaData reports major version < 9, or 9 with minor < 6. Typically happens at migration/CDC job start when the position manager opens a connection and queries metadata before choosing the LSN function.
Common situations: Pointing a migration or CDC source at PostgreSQL 9.5 or older (or a very old Greenplum/compatible fork reporting old version numbers); misrouted connection that lands on an unexpected database; product version strings from proxies that confuse metadata.
Related errors
- Unknown rowEventType: %s
- Read json data unexpected exception
- Missing required format info in createBatch()
- Invalid batch handle: statement handle %d
- Connection [%s] is not registered.
AI-assisted analysis of apache/shardingsphere@e952770a21 (2026-08-14).
Data as JSON: /api/errors/1af227f4a6339edd.
Report an issue: GitHub.