alibaba/canal · error · RuntimeException
RowKey 值为空
Error message
RowKey 值为空
What it means
HbaseEtlService import throws when a built HRow has a null rowKey after processing all mapped columns. HBase requires a non-null row key to write, so a row whose source data produced no rowKey value (composite-key columns all null AND no ROWKEY-marked column resolved) is rejected.
Source
Thrown at client-adapter/hbase/src/main/java/com/alibaba/otter/canal/client/adapter/hbase/service/HbaseEtlService.java:242
row.addCell(columnItem.getFamily(),
columnItem.getQualifier(),
TypeUtil.toBytes(val, type));
}
} else if (MappingConfig.Mode.PHOENIX == hbaseMapping.getMode()) {
PhType phType = PhType.getType(columnItem.getType());
if (columnItem.isRowKey()) {
row.setRowKey(PhTypeUtil.toBytes(val, phType));
} else {
row.addCell(columnItem.getFamily(),
columnItem.getQualifier(),
PhTypeUtil.toBytes(val, phType));
}
}
}
}
}
if (row.getRowKey() == null) throw new RuntimeException("RowKey 值为空");
rows.add(row);
complete = false;
if (i % hbaseMapping.getCommitBatch() == 0 && !rows.isEmpty()) {
hbaseTemplate.puts(hbaseMapping.getHbaseTable(), rows);
rows.clear();
complete = true;
}
i++;
impCount.incrementAndGet();
if (logger.isDebugEnabled()) {
logger.debug("successful import count:" + impCount.get());
}
}
if (!complete && !rows.isEmpty()) {
hbaseTemplate.puts(hbaseMapping.getHbaseTable(), rows);
}View on GitHub (pinned to 87be50e876)
Solutions
- Ensure every source row has non-null values in the column(s) used as the rowKey.
- Fix the mapping so rowKey references actual existing source columns.
- Cleanse null-PK source rows upstream before ETL.
- If using a single ROWKEY column, confirm exactly one column is marked ROWKEY and is populated.
Example fix
-- before: source row has NULL id -- after: backfill/cleanse so id is non-null UPDATE t_user SET id = <generated> WHERE id IS NULL;
Defensive patterns
Strategy: validation
Validate before calling
// Before ETL, ensure source rows have non-null rowKey columns
List<String> rowKeyCols = hbaseMapping.getRowKey() != null
? Arrays.asList(hbaseMapping.getRowKey().split(","))
: Collections.singletonList(hbaseMapping.getRowKeyColumn().getColumn());
for (Map<String,Object> row : data) {
boolean anyNull = rowKeyCols.stream().anyMatch(c -> row.get(c.trim()) == null);
if (anyNull) throw new IllegalStateException("Source row missing rowKey value: " + row);
} Try / catch
try {
hbaseEtlService.importData(...);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("RowKey")) {
logger.error("A source row produced no rowKey; cleanse null-PK rows upstream");
}
throw e;
} Prevention
- Guarantee non-null values in all rowKey columns of source data.
- Verify the rowKey column names exist in the source schema.
- Run a data-quality pass before ETL.
When it happens
Trigger: Running a full ETL import where a source row has null values in every column used for the rowKey (whether composite 'rowKey:' columns or a single ROWKEY column), so row.setRowKey(...) was never called.
Common situations: Source table rows with NULL primary-key columns; a mapping whose rowKey references a column that does not exist in the source data; composite rowKey where all constituent columns are null.
Related errors
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/8c26c1825aed1bd6.
Report an issue: GitHub.