apache/seatunnel · error · DebeziumException

Failed to start replication stream at <lsn>

Error message

Failed to start replication stream at <lsn>

What it means

Thrown by startStreaming when START_REPLICATION fails repeatedly and the retry count exceeds maxRetries. Each attempt waits a delay and logs a warning; once exhausted, a DebeziumException is thrown with the target LSN. If the underlying error message matches 'replication slot ... is active', an extra hint about using distinct slot names per connector is appended.

Source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-opengauss/src/main/java/io/debezium/connector/postgresql/connection/PostgresReplicationConnection.java:415

        Lsn lsn = offset;
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("starting streaming from LSN '{}'", lsn);
        }

        final int maxRetries = connectorConfig.maxRetries();
        final Duration delay = connectorConfig.retryDelay();
        int tryCount = 0;
        while (true) {
            try {
                return createReplicationStream(lsn, walPosition);
            } catch (Exception e) {
                String message = "Failed to start replication stream at " + lsn;
                if (++tryCount > maxRetries) {
                    if (e.getMessage().matches(".*replication slot .* is active.*")) {
                        message +=
                                "; when setting up multiple connectors for the same database host, please make sure to use a distinct replication slot name for each.";
                    }
                    throw new DebeziumException(message, e);
                } else {
                    LOGGER.warn(
                            message + ", waiting for {} ms and retrying, attempt number {} over {}",
                            delay,
                            tryCount,
                            maxRetries);
                    final Metronome metronome = Metronome.sleeper(delay, Clock.SYSTEM);
                    metronome.pause();
                }
            }
        }
    }

    @Override
    public void initConnection() throws SQLException, InterruptedException {
        // See https://www.postgresql.org/docs/current/logical-replication-quick-setup.html
        // For pgoutput specifically, the publication must be created before the slot.
        initPublication();

View on GitHub (pinned to cf67b549a7)

Solutions

  1. If the message says the slot is active, find and terminate the competing backend: SELECT pg_terminate_backend(pid) FROM pg_stat_replication / pg_stat_activity where the slot is in use, and ensure each connector uses a unique slot.name.
  2. Check pg_replication_slots for active_pid/conflicting slot state and kill stale walreceiver sessions left by crashed clients.
  3. Verify the start LSN is still available (pg_waldump / pg_replication_slots confirmed_flush_lsn vs min WAL retained); increase wal_keep_size or re-snapshot if WAL was purged.
  4. Increase the retry count/delay in connector configuration if failures are transient (network blips).
  5. Confirm connectivity to the primary and that the slot still exists; recreate the slot and restart with a fresh snapshot if it was dropped.

Example fix

// before: two connectors sharing one slot -> 'replication slot my_slot is active'
"slot.name": "my_slot"  // used by connector A and B
// after
"slot.name": "connector_a_slot"  // unique per connector instance
Defensive patterns

Strategy: retry

Validate before calling

-- ensure the slot is free and WAL is retained before starting
SELECT slot_name, active, active_pid, restart_lsn, confirmed_flush_lsn
FROM pg_replication_slots WHERE slot_name = 'my_slot';
SELECT pg_current_wal_lsn(), pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn))
FROM pg_replication_slots WHERE slot_name = 'my_slot';

Try / catch

try {
    stream = connection.createReplicationStream(startLsn);
} catch (DebeziumException e) {
    if (e.getMessage().contains("replication slot") && e.getMessage().contains("is active")) {
        // terminate competing backend (pg_terminate_backend(active_pid)) or use a unique slot name
    } else if (e.getMessage().startsWith("Failed to start replication stream")) {
        // check WAL retention / LSN availability, possibly re-snapshot
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: START_REPLICATION <lsn> SLOT <slot> fails on each retry: another process holds the slot (slot is active), the requested LSN is no longer available (WAL removed), network interruptions persist, or the server rejects the slot/LSN combination.

Common situations: Two connectors (or a leftover zombie walreceiver backend) using the same replication slot name on the same host; connecting to a standby that was promoted/restored causing LSN mismatch; aggressive wal_keep_size/replication slot retention removing needed WAL; long network outages exceeding the retry budget.

Related errors


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