apache/seatunnel · error · UnsupportedOperationException

Exactly once is enabled, but not found primary key or unique

Error message

Exactly once is enabled, but not found primary key or unique key for table %s

What it means

Thrown by AbstractJdbcSourceChunkSplitter.generateSplits() when the table being snapshot has no primary key or usable unique key column to chunk on, while the source is configured for exactly-once. Without a split column, snapshot splits cannot be constructed deterministically, which conflicts with exactly-once guarantees, so the connector fails fast.

Source

Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-base/src/main/java/org/apache/seatunnel/connectors/cdc/base/source/enumerator/splitter/AbstractJdbcSourceChunkSplitter.java:87

                    "Concurrent read is disabled for table {}, using single split without analysis.",
                    tableId);
            return Collections.singletonList(
                    createSnapshotSplit(null, tableId, 0, null, null, null));
        }

        try (JdbcConnection jdbc = dialect.openJdbcConnection(sourceConfig)) {
            log.info("Start splitting table {} into chunks...", tableId);
            long start = System.currentTimeMillis();

            Column splitColumn = getSplitColumn(jdbc, dialect, tableId);
            log.info(
                    "Chosen split column {} for table {}",
                    splitColumn != null ? splitColumn.name() : "null",
                    tableId);
            List<SnapshotSplit> splits = new ArrayList<>();
            if (splitColumn == null) {
                if (sourceConfig.isExactlyOnce()) {
                    throw new UnsupportedOperationException(
                            String.format(
                                    "Exactly once is enabled, but not found primary key or unique key for table %s",
                                    tableId));
                }
                SnapshotSplit singleSplit = createSnapshotSplit(jdbc, tableId, 0, null, null, null);
                splits.add(singleSplit);
                log.warn(
                        "No evenly split column found for table {}, use single split {}",
                        tableId,
                        singleSplit);
            } else {
                final List<ChunkRange> chunks;
                try {
                    chunks = splitTableIntoChunks(jdbc, tableId, splitColumn);
                } catch (SQLException e) {
                    throw new RuntimeException("Failed to split chunks for table " + tableId, e);
                }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Add a primary key or a unique NOT NULL index to the table
  2. Add a suitable unique column to the table that can serve as the split key
  3. If approximate/duplicate-tolerant snapshot is acceptable, disable exactly-once mode in the connector config so a single full-table split is used
  4. Change the captured table list to exclude the keyless table

Example fix

// before (config)
//   exact_job: { MySQL-CDC: { "exactly_once": true, "table-names": ["db.kv_no_pk"] } }
// after
//   exact_job: { MySQL-CDC: { "exactly_once": false, "table-names": ["db.kv_no_pk"] } }
// or: ALTER TABLE db.kv_no_pk ADD PRIMARY KEY (id);
Defensive patterns

Strategy: validation

Validate before calling

// Ensure the table has a usable key before enabling exactly-once:
SELECT TABLE_NAME, COUNT(*) AS keys FROM information_schema.KEY_TABLE_CONSTRAINTS
 WHERE TABLE_SCHEMA='db' AND TABLE_NAME='t' GROUP BY TABLE_NAME;
// or: SHOW KEYS FROM db.t WHERE Key_name = 'PRIMARY';

Try / catch

try { source.generateSplits(tableId); } catch (UnsupportedOperationException e) {
    LOG.warn("Table {} has no PK/unique key; falling back to non-exactly-once", tableId);
}
// Or in config: set exactly_once=false for keyless tables

Prevention

When it happens

Trigger: generateSplits() finds splitColumn == null for the table AND sourceConfig.isExactlyOnce() is true; the connector then throws UnsupportedOperationException with the table id.

Common situations: Snapshotting a view or a table deliberately created without a PRIMARY KEY; older MySQL MyISAM tables without keys; exactly_once=true (default in many setups) left enabled while pointing at keyless tables.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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