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

  1. 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.
  2. Remove the 'rowKey:' line if you intend the single-column ROWKEY mapping.
  3. Remove the 'ROWKEY' marker from any column if you intend the composite 'rowKey:' mapping.
  4. 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

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


AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14). Data as JSON: /api/errors/17565a80579e36b1. Report an issue: GitHub.