apache/seatunnel · error · SeaTunnelException
Incremental snapshot for tables requires primary key, but ta
Error message
Incremental snapshot for tables requires primary key, but table %s doesn't have primary key.
What it means
MySqlUtils.getSplitType derives the SeaTunnelRowType used for chunk splitting from the table's primary key, and throws a SeaTunnelException when the table has no primary key, because incremental snapshot chunking requires a unique, ordered key. The library fails fast instead of producing incorrect or duplicated snapshot chunks.
Source
Thrown at seatunnel-connectors-v2/connector-cdc/connector-cdc-mysql/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/mysql/utils/MySqlUtils.java:326
}
} else {
for (int i = 0; i < primaryKeyNum; i++) {
statement.setObject(i + 1, splitStart[i]);
statement.setObject(i + 1 + primaryKeyNum, splitEnd[i]);
statement.setObject(i + 1 + 2 * primaryKeyNum, splitEnd[i]);
}
}
return statement;
} catch (Exception e) {
throw new RuntimeException("Failed to build the split data read statement.", e);
}
}
public static SeaTunnelRowType getSplitType(
Table table, RelationalDatabaseConnectorConfig dbzConnectorConfig) {
List<Column> primaryKeys = table.primaryKeyColumns();
if (primaryKeys.isEmpty()) {
throw new SeaTunnelException(
String.format(
"Incremental snapshot for tables requires primary key,"
+ " but table %s doesn't have primary key.",
table.id()));
}
// use first field in primary key as the split key
return getSplitType(primaryKeys.get(0), dbzConnectorConfig);
}
public static BinlogOffset getBinlogPosition(SourceRecord dataRecord) {
return getBinlogPosition(dataRecord.sourceOffset());
}
public static BinlogOffset getBinlogPosition(Map<String, ?> offset) {
Map<String, String> offsetStrMap = new HashMap<>();
for (Map.Entry<String, ?> entry : offset.entrySet()) {
offsetStrMap.put(View on GitHub (pinned to cf67b549a7)
Solutions
- Add a primary key to the table (ALTER TABLE ... ADD PRIMARY KEY) and restart the job
- If adding a PK is impossible, exclude the table from the incremental-snapshot table list or use a non-incremental snapshot mode
- If a suitable unique NOT NULL column exists, add a PK on it
- Check table.id() in the message to identify exactly which table lacks the key
Example fix
// before CREATE TABLE orders (id BIGINT, name VARCHAR(64)); // after ALTER TABLE orders ADD PRIMARY KEY (id);
Defensive patterns
Strategy: validation
Validate before calling
ResultSet rs = st.executeQuery(
"SELECT COUNT(*) FROM information_schema.table_constraints " +
"WHERE table_schema=DATABASE() AND table_name='t' AND constraint_type='PRIMARY KEY'");
if (!rs.next() || rs.getLong(1) == 0) throw new IllegalStateException("PK required for incremental snapshot"); Try / catch
try {
SeaTunnelRowType splitType = MySqlUtils.getSplitType(table, dbzConfig);
} catch (SeaTunnelException e) {
// fall back to non-incremental snapshot or exclude table
} Prevention
- Enforce PKs on all tables registered for CDC
- Audit table lists with SHOW CREATE TABLE before enabling incremental snapshot
- Fall back to non-incremental mode for PK-less legacy tables
- Remember UNIQUE indexes don't substitute for a PK here
When it happens
Trigger: Calling getSplitType for a table whose primaryKeyColumns() is empty while incremental snapshot is enabled; typically a table created without PRIMARY KEY or with only a non-clustered unique key the connector doesn't treat as PK.
Common situations: Legacy tables without PKs added to a CDC table list; replica tables stripped of PKs; user assumes a UNIQUE index suffices but connector requires an actual primary key.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Incremental snapshot for tables requires primary key, but ta
- Incremental snapshot for tables requires primary key, but ta
- Incremental snapshot for tables requires primary key, but ta
- Incremental snapshot for tables requires primary key, but ta
- Exactly once is enabled, but not found primary key or unique
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/74d3aadd7941a8ae.
Report an issue: GitHub.