alibaba/canal · error · RuntimeException
Target column: {targetColumnName} not matched
Error message
Target column: {targetColumnName} not matched What it means
Thrown in PhoenixSyncService (insert/upsert column loop) when a target column name is not found in the cached target column type map (ctype). Unlike the condition builder, this path has a fallback: if mapAll and alter are enabled it attempts PhoenixEtlService.syncSchema to add the column; only if the column is still absent after that (and skipMissing is off) does it throw.
Source
Thrown at client-adapter/phoenix/src/main/java/com/alibaba/otter/canal/client/adapter/phoenix/service/PhoenixSyncService.java:412
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) {
if (dbMapping.isSkipMissing()) {
logger.warn("Target missing field: {}", targetColumnName);
mapLen -= 1;
continue;
} else if (dbMapping.getMapAll() && dbMapping.isAlter() && PhoenixEtlService.syncSchema(batchExecutor.getConn(), config)) {
columnsTypeCache.remove(config.getDestination() + "." + dbMapping.getDatabase() + "." + dbMapping.getTable());
ctype = getTargetColumnType(batchExecutor.getConn(), config);
type = ctype.get(Util.cleanColumn(targetColumnName).toLowerCase());
}
if (type == null) {
throw new RuntimeException("Target column: " + targetColumnName + " not matched");
}
}
insertSql.append(dbMapping.escape(targetColumnName)).append(",");
Object value = data.get(srcColumnName);
BatchExecutor.setValue(values, type, value);
}
int len = insertSql.length();
insertSql.delete(len - 1, len).append(") VALUES (");
for (int i = 0; i < mapLen; i++) {
insertSql.append("?,");
}
len = insertSql.length();
insertSql.delete(len - 1, len).append(")");
Map<String, Object> old = dml.getOld();
try {
if (old != null && !old.isEmpty()) {View on GitHub (pinned to 87be50e876)
Solutions
- Set 'skipMissing: true' in the dbMapping to drop unmapped columns instead of failing.
- Enable 'mapAll: true' and 'alter: true' so syncSchema adds missing columns automatically.
- Manually add the missing column to the target Phoenix table, or correct the targetColumns mapping / casing.
Example fix
# before dbMapping: mapAll: true alter: false # new columns cannot be added -> throws # after dbMapping: mapAll: true alter: true # auto-adds missing columns # or, to ignore missing columns dbMapping: skipMissing: true
Defensive patterns
Strategy: validation
Validate before calling
// Before syncing, verify every targetColumns key exists in the target table.
Map<String,Integer> ctype = getTargetColumnType(conn, config);
Set<String> missing = config.getDbMapping().getTargetColumns().keySet().stream()
.filter(c -> !ctype.containsKey(Util.cleanColumn(c).toLowerCase()))
.collect(Collectors.toSet());
if (!missing.isEmpty() && !config.getDbMapping().isSkipMissing()) {
throw new IllegalStateException(
"Target columns missing and skipMissing=false: " + missing
+ " - set skipMissing:true or mapAll+alter:true");
} Try / catch
try {
syncService.sync(batchExecutor, items);
} catch (RuntimeException e) {
if (e.getMessage().contains("Target column:") && e.getMessage().contains("not matched")) {
logger.error("Schema drift: a target column is missing. "
+ "Enable mapAll+alter or skipMissing, or add the column.", e);
}
throw e;
} Prevention
- Set skipMissing:true when you tolerate extra source columns.
- Enable mapAll:true and alter:true to let the adapter add missing columns automatically.
- Keep targetColumns mappings in sync with the target Phoenix table schema.
When it happens
Trigger: A DML references a column whose name is not in the target Phoenix table and not in ctype. With skipMissing=false and (mapAll=false OR alter=false OR syncSchema failed), the column remains unresolved.
Common situations: The source table gained a column not present in the target Phoenix table, and auto-alter is disabled or failed. A targetColumns mapping points at a target column that does not exist. Case mismatch when escapeUpper/escape is involved.
Related errors
- Target column: {} not matched
- No phoenix adapter found for config key: {}
- not allow to change outAdapterKey
- ERROR Config: {fileName} {errorMessage}
- dbMapping.database
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/a722813188fc6dcb.
Report an issue: GitHub.