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
- 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>';
- GRANT SELECT on the table (and schema usage) to the CDC user so catalog lookups succeed.
- Check identifier case/quoting in the connector's table list — mixed-case names often need exact case in config.
- 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
- Grant the CDC user USAGE on the schema and SELECT on catalog-visible table rows.
- Set ALTER TABLE ... REPLICA IDENTITY FULL for tables needing complete before-images.
- Match identifier case exactly in connector table configs (quote mixed-case names).
- Re-read table metadata after DDL (rename/drop/create) or restart the task.
- Verify catalog behavior differences on OpenGauss when using the vendored Postgres connection code.
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
- Interrupted while waiting for valid replication slot info
- The offset to start reading from has been removed from the d
- received unexpected exception will perform keep alive
- Table ${tableId} does not have a full replica identity, plea
- The "before" field of ${op} operation is null, if you are us
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/0caf4adbb2535a8c.
Report an issue: GitHub.