alibaba/canal · error · RuntimeException
已配置了复合主键作为RowKey,无需再指定RowKey列
Error message
已配置了复合主键作为RowKey,无需再指定RowKey列
What it means
MappingConfig.validate() rejects a mapping that configures BOTH a composite rowKey (hbaseMapping.rowKey, a comma-separated column list) AND a single rowKeyColumn (a column flagged as ROWKEY in the columns map). These are two mutually exclusive rowKey strategies; specifying both is a configuration contradiction.
Source
Thrown at client-adapter/hbase/src/main/java/com/alibaba/otter/canal/client/adapter/hbase/config/MappingConfig.java:83
public AdapterMapping getMapping() {
return hbaseMapping;
}
public void validate() {
if (hbaseMapping.database == null || hbaseMapping.database.isEmpty()) {
throw new NullPointerException("hbaseMapping.database");
}
if (hbaseMapping.table == null || hbaseMapping.table.isEmpty()) {
throw new NullPointerException("hbaseMapping.table");
}
if (hbaseMapping.hbaseTable == null || hbaseMapping.hbaseTable.isEmpty()) {
throw new NullPointerException("hbaseMapping.hbaseTable");
}
if (hbaseMapping.mode == null) {
throw new NullPointerException("hbaseMapping.mode");
}
if (hbaseMapping.rowKey != null && hbaseMapping.rowKeyColumn != null) {
throw new RuntimeException("已配置了复合主键作为RowKey,无需再指定RowKey列");
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MappingConfig config = (MappingConfig) o;
return hbaseMapping != null ? hbaseMapping.equals(config.hbaseMapping) : config.hbaseMapping == null;
}
@Override
public int hashCode() {
return hbaseMapping != null ? hbaseMapping.hashCode() : 0;
}
View on GitHub (pinned to 87be50e876)
Solutions
- Choose ONE rowKey strategy: either set 'rowKey: c1,c2' for a composite key, OR mark a single column value as 'ROWKEY' / 'ROWKEYLEN:n', but not both.
- Remove the 'rowKey:' line if you intend the single-column ROWKEY mapping.
- Remove the 'ROWKEY' marker from any column if you intend the composite 'rowKey:' mapping.
- Re-validate the YAML after the edit.
Example fix
# before (both set)
hbaseMapping:
rowKey: id,ts
columns:
id: ROWKEY
# after (composite only)
hbaseMapping:
rowKey: id,ts
columns:
id: CF:id Defensive patterns
Strategy: validation
Validate before calling
MappingConfig.HbaseMapping m = config.getHbaseMapping();
boolean hasCompositeKey = m.getRowKey() != null;
boolean hasRowKeyColumn = m.getRowKeyColumn() != null;
if (hasCompositeKey && hasRowKeyColumn) {
throw new IllegalStateException("Specify either rowKey (composite) or a single ROWKEY column, not both");
} Try / catch
try {
config.validate();
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("RowKey")) {
logger.error("Remove either rowKey or the ROWKEY column marker");
}
throw e;
} Prevention
- Pick exactly one rowKey strategy per mapping.
- Review the columns map for any value starting with 'ROWKEY' when 'rowKey:' is also set.
- Lint the mapping in CI.
When it happens
Trigger: HBase mapping YAML that sets 'hbaseMapping.rowKey: col1,col2' AND also has a column whose value starts with 'ROWKEY' (which auto-populates rowKeyColumn).
Common situations: Authoring a mapping and using both the composite-key and single-ROWKEY-column syntax by mistake; merging two config snippets.
Related errors
- hbaseMapping.database
- hbaseMapping.table
- hbaseMapping.hbaseTable
- hbaseMapping.mode
- clusterId and serverId are all empty
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/17565a80579e36b1.
Report an issue: GitHub.