apache/seatunnel · error · SeaTunnelException

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

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.

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)

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.