apache/seatunnel · error · IllegalStateException
Cannot find table schema for table
Error message
Cannot find table schema for table ${tableId}. Tried table id: ${tableIdWithoutCatalog}. What it means
PostgresSnapshotSplitReadTask.resolveTable looks up the table schema in the Debezium/SeaTunnel table catalog. It first falls back to the connector's configured database name when the TableId has no catalog; if the catalog is still empty it throws IllegalStateException 'Cannot find table schema for table <tableId>. Tried table id: <tableIdWithoutCatalog>.', because snapshot events cannot be converted without schema metadata.
Solutions
- Set `database-name` explicitly in the PostgreSQL CDC source options.
- Verify the table still exists (`\d+ <schema>.<table>`) and matches the configured table names exactly, including case.
- Check the `table-names` config for typos or wrong schema qualification.
- Re-enumerate splits / restart the job so the catalog is rebuilt after DDL changes.
Example fix
// before
PostgresIncrementalSource.builder()
.tableNames("public.orders")
// database-name missing
// after
PostgresIncrementalSource.builder()
.tableNames("public.orders")
.database("mydb")
.build(); Defensive patterns
Strategy: validation
Validate before calling
// Verify each configured table resolves before submitting
for (String t : tableNames) {
// t must include schema, e.g. public.orders; database-name must be set
} Try / catch
try {
job.execute();
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Cannot find table schema")) {
// fix database-name/table-names config and resubmit
}
} Prevention
- Always set database-name in PostgreSQL CDC source options
- Use fully-qualified table names (schema.table) with correct case
- Check that tables exist and are unchanged between split enumeration and execution
- Avoid cross-database captures unless explicitly configured
When it happens
Trigger: createDataEvents calls resolveTable for a split's TableId whose catalog part is null/empty AND connectorConfig.databaseName() is also null/empty, or the table is simply absent from the catalog after both attempts.
Common situations: `database-name` not set in source config while the table id lacks a catalog; table dropped or renamed between split enumeration and snapshot execution; case-sensitivity mismatches (quoted identifiers) causing catalog lookup misses; capturing tables across databases with wrong database-name.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Read snapshot for split
- A slot marked as temporary or with an exported snapshot was…
- Cannot drop replication slot
- Cannot find table schema for table
- Cannot obtain valid replication slot
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/88659a06865aa08f.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-postgres/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/postgres/source/reader/snapshot/PostgresSnapshotSplitReadTask.java:185
dispatcher.getSnapshotChangeEventReceiver();
log.debug("Snapshotting table {}", tableId);
createDataEventsForTable(snapshotContext, snapshotReceiver, resolveTable(tableId));
snapshotReceiver.completeSnapshot();
}
private Table resolveTable(TableId tableId) {
TableId tableIdWithoutCatalog = new TableId(null, tableId.schema(), tableId.table());
Table table = databaseSchema.tableFor(tableIdWithoutCatalog);
if (table != null) {
return table;
}
String catalog = tableId.catalog();
if (catalog == null || catalog.isEmpty()) {
catalog = connectorConfig.databaseName();
}
if (catalog == null || catalog.isEmpty()) {
throw new IllegalStateException(
String.format(
"Cannot find table schema for table %s. Tried table id: %s.",
tableId, tableIdWithoutCatalog));
}
TableId tableIdWithCatalog = new TableId(catalog, tableId.schema(), tableId.table());
table = databaseSchema.tableFor(tableIdWithCatalog);
if (table != null) {
return table;
}
throw new IllegalStateException(
String.format(
"Cannot find table schema for table %s. Tried table ids: %s and %s.",
tableId, tableIdWithoutCatalog, tableIdWithCatalog));
}
/** Dispatches the data change events for the records of a single table. */View on GitHub (pinned to cf67b549a7)