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

  1. Set `database-name` explicitly in the PostgreSQL CDC source options.
  2. Verify the table still exists (`\d+ <schema>.<table>`) and matches the configured table names exactly, including case.
  3. Check the `table-names` config for typos or wrong schema qualification.
  4. 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

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


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)