apache/seatunnel · error · SeaTunnelException

Error getting current Lsn/txId

Error message

Error getting current Lsn/txId ${e.getMessage()}

What it means

PostgresUtils.currentLsn obtains the current WAL log sequence number and transaction id through Debezium's PostgresConnection (currentXLogLocation/currentTransactionId). Any SQLException while reading these is wrapped in SeaTunnelException 'Error getting current Lsn/txId <message>'; a subsequent commit failure produces the related 'JDBC connection fails to commit' error.

Solutions

  1. Read e.getMessage() in the error for the root SQL failure (usually connection or privilege)
  2. Confirm wal_level=logical and the CDC user has REPLICATION privilege (pg_roles rolreplication)
  3. Test the replication connection and slot: pg_replication_slots should show your slot active/available
  4. Check connection stability (keepalives, firewall timeouts) and restart the job — LSN read is retried on next startup

Example fix

-- on the server
ALTER ROLE cdc_user WITH REPLICATION;
ALTER SYSTEM SET wal_level = 'logical';
Defensive patterns

Strategy: try-catch

Validate before calling

SHOW wal_level;                       -- must be 'logical'
SELECT rolreplication FROM pg_roles WHERE rolname = 'cdc_user'; -- must be true

Try / catch

try { Lsn lsn = PostgresUtils.currentLsn(conn); } catch (SeaTunnelException e) {
    log.error("LSN read failed: {} cause={}", e.getMessage(), e.getCause()); throw e;
}

Prevention

When it happens

Trigger: The replication connection used to read the current LSN fails — connection dropped, the replication slot/replication privileges are missing, Postgres restarted, or the underlying query for pg_current_wal_lsn()/txid_current() errors.

Common situations: Server restart or failover during startup; user lacking REPLICATION privilege; wal_level not set to logical; network/firewall dropping long-lived connections; slot conflicts after promotion.

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

Appendix: source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-postgres/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/postgres/utils/PostgresUtils.java:304

    public static LsnOffset getLsnPosition(Map<String, ?> offset) {
        Map<String, String> offsetStrMap = new HashMap<>();
        for (Map.Entry<String, ?> entry : offset.entrySet()) {
            offsetStrMap.put(
                    entry.getKey(), entry.getValue() == null ? null : entry.getValue().toString());
        }
        return new LsnOffset(offsetStrMap);
    }

    /** Fetch current largest log sequence number (LSN) of the database. */
    public static LsnOffset currentLsn(PostgresConnection jdbcConnection) {
        Long lsn;
        Long txId;
        try {
            lsn = jdbcConnection.currentXLogLocation();
            txId = jdbcConnection.currentTransactionId();
            log.trace("Read xlogStart at '{}' from transaction '{}'", Lsn.valueOf(lsn), txId);
        } catch (SQLException e) {
            throw new SeaTunnelException("Error getting current Lsn/txId " + e.getMessage(), e);
        }

        try {
            jdbcConnection.commit();
        } catch (SQLException e) {
            throw new SeaTunnelException("JDBC connection fails to commit: " + e.getMessage(), e);
        }

        Map<String, String> offsetMap = new HashMap<>();
        offsetMap.put(SourceInfo.LSN_KEY, lsn.toString());
        if (txId != null) {
            offsetMap.put(SourceInfo.TXID_KEY, txId.toString());
        }
        offsetMap.put(
                SourceInfo.TIMESTAMP_USEC_KEY,
                String.valueOf(Conversions.toEpochMicros(Instant.MIN)));
        return LsnOffset.of(offsetMap);
    }

View on GitHub (pinned to cf67b549a7)