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
- Add a primary key or a unique NOT NULL index to the table
- Add a suitable unique column to the table that can serve as the split key
- If approximate/duplicate-tolerant snapshot is acceptable, disable exactly-once mode in the connector config so a single full-table split is used
- 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
- Enforce primary keys on all CDC-captured tables
- Audit target tables for PK/unique keys before enabling exactly_once
- Set exactly_once=false explicitly for known keyless tables
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
- Failed to split chunks for table " + tableId
- Generate Splits for table %s error
- Failed to build the split data read statement.
- Failed to discover captured tables for enumerator
- Failed to discover remaining tables to capture
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/1fe65ae07ee5fc8a.
Report an issue: GitHub.