{"record":{"id":"7c50f15db07f3d4b","repo":"apache/seatunnel","slug":"incremental-snapshot-for-tables-requires-primary-k","errorCode":null,"errorMessage":"Incremental snapshot for tables requires primary key, but table ${table.id()} doesn't have primary key.","messagePattern":"Incremental snapshot for tables requires primary key, but table (.+?) doesn't have primary key\\.","errorType":"exception","errorClass":"SeaTunnelException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-cdc/connector-cdc-db2/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/db2/utils/Db2Utils.java","lineNumber":242,"sourceCode":"                        chunkSize);\n        return jdbc.prepareQueryAndMap(\n                query,\n                ps -> ps.setObject(1, includedLowerBound),\n                rs -> {\n                    if (!rs.next()) {\n                        // this should never happen\n                        throw new SQLException(\n                                String.format(\n                                        \"No result returned after running query [%s]\", query));\n                    }\n                    return rs.getObject(1);\n                });\n    }\n\n    public static SeaTunnelRowType getSplitType(Table table) {\n        List<Column> primaryKeys = table.primaryKeyColumns();\n        if (primaryKeys.isEmpty()) {\n            throw new SeaTunnelException(\n                    String.format(\n                            \"Incremental snapshot for tables requires primary key,\"\n                                    + \" but table %s doesn't have primary key.\",\n                            table.id()));\n        }\n\n        // use first field in primary key as the split key\n        return getSplitType(primaryKeys.get(0));\n    }\n\n    public static SeaTunnelRowType getSplitType(Column splitColumn) {\n        return new SeaTunnelRowType(\n                new String[] {splitColumn.name()},\n                new SeaTunnelDataType<?>[] {Db2TypeUtils.convertFromColumn(splitColumn)});\n    }\n\n    public static Offset getLsn(SourceRecord record) {\n        return getLsnPosition(record.sourceOffset());","sourceCodeStart":224,"sourceCodeEnd":260,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-cdc/connector-cdc-db2/src/main/java/org/apache/seatunnel/connectors/seatunnel/cdc/db2/utils/Db2Utils.java#L224-L260","documentation":"Incremental snapshot chunking requires a primary key to split the table. Db2Utils.getSplitType inspects the Debezium Table's primary-key columns and throws SeaTunnelException when the table has none, refusing to snapshot a key-less table.","triggerScenarios":"Enabling incremental snapshot (scan.incremental.snapshot.enabled=true or default in newer versions) on a DB2 table with no primary key defined in its schema metadata.","commonSituations":"Legacy DB2 tables created without PK; keys exist physically but are not declared in DDL so schema metadata sees none; connector reads the wrong schema/database so the PK isn't picked up.","solutions":["Add a primary key (or a NOT NULL unique key recognized as PK) to the table","Disable incremental snapshot so the table is read by the legacy snapshot mechanism","Choose a table that has a primary key","Verify the schema/table resolution picks the intended table that does have a PK"],"exampleFix":"// before\nALTER TABLE MYSCHEMA.MYTABLE ...; -- no PK\n// after\nALTER TABLE MYSCHEMA.MYTABLE ADD PRIMARY KEY (ID);","handlingStrategy":"validation","validationCode":"// Verify PK before enabling incremental snapshot\nSELECT KC.NAME FROM SYSCAT.KEYCOLUSE KC JOIN SYSCAT.TABCONST TC ON KC.CONSTNAME = TC.CONSTNAME AND KC.TABSCHEMA = TC.TABSCHEMA AND KC.TABNAME = TC.TABNAME WHERE TC.TYPE = 'P' AND TC.TABSCHEMA='MYSCHEMA' AND TC.TABNAME='MYTABLE';","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure every snapshot target table has a declared primary key","Or explicitly disable incremental snapshot for key-less tables","Check schema resolution reads the intended database"],"tags":["db2","cdc","primary-key","config"],"backgroundTag":"missing-required-config-field","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}