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

  1. Ensure every source row has non-null values in the column(s) used as the rowKey.
  2. Fix the mapping so rowKey references actual existing source columns.
  3. Cleanse null-PK source rows upstream before ETL.
  4. 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

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.