alibaba/canal · error · RuntimeException

Target column: {} not matched

Error message

Target column: {} not matched

What it means

Thrown by ClickHouseBatchSyncService.insert during a batch INSERT sync when a column present in the computed columnsMap (derived from targetColumns mapping or source data) has no matching entry in the target ClickHouse table's column-type map (ctype). This means the mapping references a target column that does not exist (under that name/casing) in the destination ClickHouse table.

Source

Thrown at client-adapter/clickhouse/src/main/java/com/alibaba/otter/canal/client/adapter/clickhouse/service/ClickHouseBatchSyncService.java:325

            insertSql.append("?,");
        }
        len = insertSql.length();
        insertSql.delete(len - 1, len).append(")");

        Map<String, Integer> ctype = getTargetColumnType(batchExecutor.getConn(), config);

        List<List<Map<String, ?>>> values = new ArrayList<>();
        boolean flag = false;
        for (Map.Entry<String, String> entry : columnsMap.entrySet()) {
            String targetColumnName = entry.getKey();
            String srcColumnName = entry.getValue();
            if (srcColumnName == null) {
                srcColumnName = Util.cleanColumn(targetColumnName);
            }

            Integer type = ctype.get(Util.cleanColumn(targetColumnName).toLowerCase());
            if (type == null) {
                throw new RuntimeException("Target column: " + targetColumnName + " not matched");
            }
            for (int i = 0; i < clearDmls.size(); i++) {
                Map<String, Object> dmlData = clearDmls.get(i).getData();
                List<Map<String, ?>> item;
                if (flag == false) {
                    item = new ArrayList<>();
                    values.add(item);
                } else {
                    item = values.get(i);
                }
                Object value = dmlData.get(srcColumnName);
                BatchExecutor.setValue(item, type, value);
            }
            flag = true;
        }

        try {
            batchExecutor.batchExecute(insertSql.toString(), values);

View on GitHub (pinned to 87be50e876)

Solutions

  1. Compare the mapping's target column names against the actual ClickHouse table columns (DESCRIBE TABLE) and fix any mismatch.
  2. Align casing: enable dbMapping.caseInsensitive=true if the target is case-insensitive, or correct the case in targetColumns.
  3. If the source gained a column, add the corresponding column to the ClickHouse target table (ALTER TABLE ADD COLUMN).
  4. Remove stale entries from targetColumns that reference non-existent target columns.
  5. When using mapAll, ensure every mapped source column has a corresponding target column.

Example fix

# before (mapping targetColumns references 'user_id' but ClickHouse table has 'userid'):
dbMapping:
  targetColumns:
    user_id: user_id
# after:
ALTER TABLE target_table ADD COLUMN user_id ...;
# or correct the mapping:
dbMapping:
  targetColumns:
    userid: userid
Defensive patterns

Strategy: validation

Validate before calling

// Before enabling sync, verify every mapped target column exists in the ClickHouse table.
// (Mirrors the internal ctype lookup that throws.)
try (Connection conn = dataSource.getConnection();
     Statement st = conn.createStatement();
     ResultSet rs = st.executeQuery("DESCRIBE TABLE " + targetTable)) {
    Set<String> cols = new HashSet<>();
    while (rs.next()) cols.add(rs.getString(1).toLowerCase());
    for (String mapped : targetColumnsMap.keySet()) {
        if (!cols.contains(mapped.toLowerCase())) {
            throw new IllegalStateException("Mapped target column '" + mapped + "' missing from " + targetTable);
        }
    }
}

Try / catch

try {
    adapter.sync(dmls);
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().contains("not matched")) {
        logger.error("Target column mismatch; run DESCRIBE TABLE and align mapping/case.");
    }
    throw e;
}

Prevention

When it happens

Trigger: The targetColumns mapping names a column not present in the ClickHouse target table; the target table schema was altered (column dropped/renamed) after the mapping was written; case mismatch between the mapping column name and the ClickHouse column when caseInsensitive is off; mapAll mode including a source column whose derived target name is absent from the target table.

Common situations: Source schema evolved (new column) but ClickHouse target table not migrated; targetColumns map pointing at a renamed/deleted ClickHouse column; case sensitivity mismatch (ClickHouse column is lowercase, mapping uses mixed case) with caseInsensitive=false; typos in targetColumns keys.

Related errors


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