apache/seatunnel · warning

Cannot determine REPLICA IDENTITY information for table '{}'

Error message

Cannot determine REPLICA IDENTITY information for table '{}'

What it means

The OpenGauss/PostgreSQL connector (vendored Debezium PostgresConnection.readReplicaIdentityInfo) queries pg_class.relreplident for the target table; if the query returns no row, the connector logs this WARN and falls back to ServerInfo.ReplicaIdentity.parseFromDB("") — i.e. it proceeds with a default/parsed-empty replica identity instead of the real one. This can later cause incorrect before-image data on UPDATE/DELETE if the assumed identity is wrong.

Source

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

                "SELECT relreplident FROM pg_catalog.pg_class c "
                        + "LEFT JOIN pg_catalog.pg_namespace n ON c.relnamespace=n.oid "
                        + "WHERE n.nspname=? and c.relname=?";
        String schema =
                tableId.schema() != null && tableId.schema().length() > 0
                        ? tableId.schema()
                        : "public";
        StringBuilder replIdentity = new StringBuilder();
        prepareQuery(
                statement,
                stmt -> {
                    stmt.setString(1, schema);
                    stmt.setString(2, tableId.table());
                },
                rs -> {
                    if (rs.next()) {
                        replIdentity.append(rs.getString(1));
                    } else {
                        LOGGER.warn(
                                "Cannot determine REPLICA IDENTITY information for table '{}'",
                                tableId);
                    }
                });
        return ServerInfo.ReplicaIdentity.parseFromDB(replIdentity.toString());
    }

    /**
     * Returns the current state of the replication slot
     *
     * @param slotName the name of the slot
     * @param pluginName the name of the plugin used for the desired slot
     * @return the {@link SlotState} or null, if no slot state is found
     * @throws SQLException
     */
    public SlotState getReplicationSlotState(String slotName, String pluginName)
            throws SQLException {
        ServerInfo.ReplicationSlot slot;

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Verify the table exists: SELECT relreplident FROM pg_class c JOIN pg_namespace n ON c.relnamespace=n.oid WHERE n.nspname='<schema>' AND c.relname='<table>';
  2. GRANT SELECT on the table (and schema usage) to the CDC user so catalog lookups succeed.
  3. Check identifier case/quoting in the connector's table list — mixed-case names often need exact case in config.
  4. Set the replica identity explicitly: ALTER TABLE <t> REPLICA IDENTITY FULL, then restart the task so metadata is re-read.

Example fix

// before: table invisible to CDC user
CREATE USER st WITH PASSWORD '***';
// after
CREATE USER st WITH PASSWORD '***';
GRANT USAGE ON SCHEMA public TO st;
GRANT SELECT ON public.mytable TO st;
ALTER TABLE public.mytable REPLICA IDENTITY FULL;
Defensive patterns

Strategy: validation

Validate before calling

SELECT c.relreplident FROM pg_class c JOIN pg_namespace n ON c.relnamespace=n.oid
WHERE n.nspname='<schema>' AND c.relname='<table>'; -- must return exactly one row

Try / catch

ResultSet rs = ...; if (!rs.next()) { LOGGER.warn("Cannot determine REPLICA IDENTITY information for table '{}'", tableId); // fall back to default identity, or fail fast if before-images are required }

Prevention

When it happens

Trigger: replicaIdentity() calls readReplicaIdentityInfo which runs a parameterized query on pg_class with schema name and table name; rs.next() is false — the table row is not visible to the querying user or the tableId (schema.table) does not exist at that moment (renamed/dropped between metadata fetch and this query, or case-sensitivity/quoting mismatch).

Common situations: CDC user lacking SELECT privileges on the system catalog row for the schema/table; table created/renamed after the initial metadata snapshot; case-sensitive identifiers (mixed-case table names) mishandled; OpenGauss vs PostgreSQL catalog differences in vendored code.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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