alibaba/canal · error · RuntimeException
empty rowKey
Error message
empty rowKey
What it means
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.
Source
Thrown at client-adapter/hbase/src/main/java/com/alibaba/otter/canal/client/adapter/hbase/service/HbaseSyncService.java:82
// return;
// }
int i = 1;
boolean complete = false;
List<HRow> rows = new ArrayList<>();
for (Map<String, Object> r : data) {
HRow hRow = new HRow();
// 拼接复合rowKey
if (hbaseMapping.getRowKey() != null) {
String[] rowKeyColumns = hbaseMapping.getRowKey().trim().split(",");
String rowKeyVale = getRowKeys(rowKeyColumns, r);
// params.put("rowKey", Bytes.toBytes(rowKeyVale));
hRow.setRowKey(Bytes.toBytes(rowKeyVale));
}
convertData2Row(hbaseMapping, hRow, r);
if (hRow.getRowKey() == null) {
throw new RuntimeException("empty rowKey");
}
rows.add(hRow);
complete = false;
if (i % config.getHbaseMapping().getCommitBatch() == 0 && !rows.isEmpty()) {
hbaseTemplate.puts(hbaseMapping.getHbaseTable(), rows);
rows.clear();
complete = true;
}
i++;
}
if (!complete && !rows.isEmpty()) {
hbaseTemplate.puts(hbaseMapping.getHbaseTable(), rows);
}
}
/**
* 将Map数据转换为HRow行数据View on GitHub (pinned to 87be50e876)
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.
Example fix
# before (no rowKey)
hbaseMapping:
columns:
id: CF:id
# after
hbaseMapping:
columns:
id: ROWKEY
name: CF:name Defensive patterns
Strategy: validation
Validate before calling
// Verify a rowKey strategy is configured before sync
MappingConfig.HbaseMapping m = config.getHbaseMapping();
boolean hasKey = m.getRowKey() != null || m.getRowKeyColumn() != null;
if (!hasKey) {
throw new IllegalStateException("HBase mapping needs a rowKey or a ROWKEY column");
} Try / catch
try {
hbaseSyncService.sync(config, dml);
} catch (RuntimeException e) {
if ("empty rowKey".equals(e.getMessage())) {
logger.error("INSERT could not build a rowKey; configure rowKey/ROWKEY and check column names");
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/3b94489a752f90e3.
Report an issue: GitHub.