apache/seatunnel · warning

Cannot obtain valid replication slot '{}' for plugin '{}' an

Error message

Cannot obtain valid replication slot '{}' for plugin '{}' and database '{}' [during attempt {} out of {}, concurrent tx probably blocks taking snapshot.

What it means

This is a warning emitted while polling for a PostgreSQL/openGauss logical replication slot's info. The connector fetched the slot metadata via pg_replication_slots but got null (slot missing, or inactive with no confirmed_flush_lsn), meaning a concurrent transaction is likely holding back the slot snapshot/advance. It retries up to MAX_ATTEMPTS_FOR_OBTAINING_REPLICATION_SLOT times before failing hard with a DebeziumException.

Source

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

     *     ServerInfo.ReplicationSlot#INVALID} if the slot is not valid
     * @throws SQLException is thrown by the underyling jdbc driver
     * @throws InterruptedException is thrown if we don't return an answer within the set number of
     *     retries
     */
    @VisibleForTesting
    ServerInfo.ReplicationSlot readReplicationSlotInfo(String slotName, String pluginName)
            throws SQLException, InterruptedException {
        final String database = database();
        final Metronome metronome =
                Metronome.parker(PAUSE_BETWEEN_REPLICATION_SLOT_RETRIEVAL_ATTEMPTS, Clock.SYSTEM);

        for (int attempt = 1; attempt <= MAX_ATTEMPTS_FOR_OBTAINING_REPLICATION_SLOT; attempt++) {
            final ServerInfo.ReplicationSlot slot = fetchReplicationSlotInfo(slotName, pluginName);
            if (slot != null) {
                LOGGER.info("Obtained valid replication slot {}", slot);
                return slot;
            }
            LOGGER.warn(
                    "Cannot obtain valid replication slot '{}' for plugin '{}' and database '{}' [during attempt {} out of {}, concurrent tx probably blocks taking snapshot.",
                    slotName,
                    pluginName,
                    database,
                    attempt,
                    MAX_ATTEMPTS_FOR_OBTAINING_REPLICATION_SLOT);
            metronome.pause();
        }

        throw new ConnectException(
                "Unable to obtain valid replication slot. "
                        + "Make sure there are no long-running transactions running in parallel as they may hinder the allocation of the replication slot when starting this connector");
    }

    protected ServerInfo.ReplicationSlot queryForSlot(
            String slotName,
            String database,
            String pluginName,

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Verify the slot exists: SELECT slot_name, plugin, active FROM pg_replication_slots; and create it if missing (SELECT pg_create_logical_replication_slot('<slot>','<plugin>')).
  2. Kill or wait for long-running transactions blocking the slot (SELECT pid, state, xact_start FROM pg_stat_activity WHERE state <> 'idle';).
  3. Ensure each connector uses a unique replication slot name; sharing a slot across concurrent connectors causes contention.
  4. Increase the retry window if transactions are expected (adjust MAX_ATTEMPTS_FOR_OBTAINING_REPLICATION_SLOT or slot.name config) and rerun.

Example fix

// before: two connectors sharing slot 'dbz'
{"debezium.properties": {"slot.name": "dbz"}} // connector A and B
// after
// connector A: {"slot.name": "dbz_a"}
// connector B: {"slot.name": "dbz_b"}
Defensive patterns

Strategy: retry

Validate before calling

SELECT slot_name, plugin, active, confirmed_flush_lsn FROM pg_replication_slots WHERE slot_name = '<slot>' AND plugin = '<plugin>'; -- require one active=false row before starting

Try / catch

for (int attempt = 1; attempt <= 6; attempt++) { if (slotAvailable()) break; Thread.sleep(10_000 * attempt); }

Prevention

When it happens

Trigger: getReplicationSlotState -> readReplicationSlotInfo loop: fetchReplicationSlotInfo returns null on every attempt for the configured slotName/plugin/database — typically right after slot creation while another transaction is open, or when the slot was dropped externally.

Common situations: Long-running transactions on the database blocking WAL/slot snapshot export; another connector instance consumed or dropped the same slot; slot name typo so the slot does not exist; Postgres restart mid-setup.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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