{"record":{"id":"3b94489a752f90e3","repo":"alibaba/canal","slug":"empty-rowkey","errorCode":null,"errorMessage":"empty rowKey","messagePattern":"empty rowKey","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"client-adapter/hbase/src/main/java/com/alibaba/otter/canal/client/adapter/hbase/service/HbaseSyncService.java","lineNumber":82,"sourceCode":"        // return;\n        // }\n        int i = 1;\n        boolean complete = false;\n        List<HRow> rows = new ArrayList<>();\n        for (Map<String, Object> r : data) {\n            HRow hRow = new HRow();\n\n            // 拼接复合rowKey\n            if (hbaseMapping.getRowKey() != null) {\n                String[] rowKeyColumns = hbaseMapping.getRowKey().trim().split(\",\");\n                String rowKeyVale = getRowKeys(rowKeyColumns, r);\n                // params.put(\"rowKey\", Bytes.toBytes(rowKeyVale));\n                hRow.setRowKey(Bytes.toBytes(rowKeyVale));\n            }\n\n            convertData2Row(hbaseMapping, hRow, r);\n            if (hRow.getRowKey() == null) {\n                throw new RuntimeException(\"empty rowKey\");\n            }\n            rows.add(hRow);\n            complete = false;\n            if (i % config.getHbaseMapping().getCommitBatch() == 0 && !rows.isEmpty()) {\n                hbaseTemplate.puts(hbaseMapping.getHbaseTable(), rows);\n                rows.clear();\n                complete = true;\n            }\n            i++;\n        }\n        if (!complete && !rows.isEmpty()) {\n            hbaseTemplate.puts(hbaseMapping.getHbaseTable(), rows);\n        }\n\n    }\n\n    /**\n     * 将Map数据转换为HRow行数据","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/client-adapter/hbase/src/main/java/com/alibaba/otter/canal/client/adapter/hbase/service/HbaseSyncService.java#L64-L100","documentation":"HbaseSyncService.insert() throws 'empty rowKey' after building each HRow if its rowKey is still null. This happens when hbaseMapping.getRowKey() is null (no composite key) and convertData2Row did not encounter a ROWKEY-marked column as the first entry — i.e. no column was configured as the rowKey.","triggerScenarios":"An INSERT DML is synced for an HBase mapping that has neither a composite 'rowKey:' nor any column marked ROWKEY, so the row never receives a key.","commonSituations":"Mapping YAML with a 'columns:' map but no rowKey/ROWKEY designation; the rowKey column name in the mapping does not match the actual synced column name.","solutions":["Configure a rowKey: either set 'rowKey: <col>' (composite) or mark exactly one column value as 'ROWKEY' in the columns map.","Confirm the rowKey column name matches the column name in the incoming DML data exactly (case-sensitive).","Ensure the rowKey column value is non-null in the data.","Re-validate the mapping config."],"exampleFix":"# before (no rowKey)\nhbaseMapping:\n  columns:\n    id: CF:id\n\n# after\nhbaseMapping:\n  columns:\n    id: ROWKEY\n    name: CF:name","handlingStrategy":"validation","validationCode":"// Verify a rowKey strategy is configured before sync\nMappingConfig.HbaseMapping m = config.getHbaseMapping();\nboolean hasKey = m.getRowKey() != null || m.getRowKeyColumn() != null;\nif (!hasKey) {\n    throw new IllegalStateException(\"HBase mapping needs a rowKey or a ROWKEY column\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    hbaseSyncService.sync(config, dml);\n} catch (RuntimeException e) {\n    if (\"empty rowKey\".equals(e.getMessage())) {\n        logger.error(\"INSERT could not build a rowKey; configure rowKey/ROWKEY and check column names\");\n    }\n    throw e;\n}","preventionTips":["Always configure exactly one rowKey strategy per HBase mapping.","Ensure the rowKey column name matches the DML column name exactly.","Confirm rowKey column values are non-null."],"tags":["hbase-adapter","sync","rowkey","insert"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}