{"record":{"id":"a722813188fc6dcb","repo":"alibaba/canal","slug":"target-column-targetcolumnname-not-matched","errorCode":null,"errorMessage":"Target column: {targetColumnName} not matched","messagePattern":"Target column: (.+?) not matched","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"client-adapter/phoenix/src/main/java/com/alibaba/otter/canal/client/adapter/phoenix/service/PhoenixSyncService.java","lineNumber":412,"sourceCode":"            String targetColumnName = entry.getKey();\n            String srcColumnName = entry.getValue();\n            if (srcColumnName == null) {\n                srcColumnName = Util.cleanColumn(targetColumnName);\n            }\n\n            Integer type = ctype.get(Util.cleanColumn(targetColumnName).toLowerCase());\n            if (type == null) {\n                if (dbMapping.isSkipMissing()) {\n                    logger.warn(\"Target missing field: {}\", targetColumnName);\n                    mapLen -= 1;\n                    continue;\n                } else if (dbMapping.getMapAll() && dbMapping.isAlter() && PhoenixEtlService.syncSchema(batchExecutor.getConn(), config)) {\n                    columnsTypeCache.remove(config.getDestination() + \".\" + dbMapping.getDatabase() + \".\" + dbMapping.getTable());\n                    ctype = getTargetColumnType(batchExecutor.getConn(), config);\n                    type = ctype.get(Util.cleanColumn(targetColumnName).toLowerCase());\n                }\n                if (type == null) {\n                    throw new RuntimeException(\"Target column: \" + targetColumnName + \" not matched\");\n                }\n            }\n            insertSql.append(dbMapping.escape(targetColumnName)).append(\",\");\n            Object value = data.get(srcColumnName);\n            BatchExecutor.setValue(values, type, value);\n        }\n\n        int len = insertSql.length();\n        insertSql.delete(len - 1, len).append(\") VALUES (\");\n        for (int i = 0; i < mapLen; i++) {\n            insertSql.append(\"?,\");\n        }\n        len = insertSql.length();\n        insertSql.delete(len - 1, len).append(\")\");\n\n        Map<String, Object> old = dml.getOld();\n        try {\n            if (old != null && !old.isEmpty()) {","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/alibaba/canal/blob/87be50e87686a3e8af08c368d0e1ffd1f59eb04a/client-adapter/phoenix/src/main/java/com/alibaba/otter/canal/client/adapter/phoenix/service/PhoenixSyncService.java#L394-L430","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\ndbMapping:\n  mapAll: true\n  alter: false      # new columns cannot be added -> throws\n# after\ndbMapping:\n  mapAll: true\n  alter: true       # auto-adds missing columns\n# or, to ignore missing columns\ndbMapping:\n  skipMissing: true","handlingStrategy":"validation","validationCode":"// Before syncing, verify every targetColumns key exists in the target table.\nMap<String,Integer> ctype = getTargetColumnType(conn, config);\nSet<String> missing = config.getDbMapping().getTargetColumns().keySet().stream()\n    .filter(c -> !ctype.containsKey(Util.cleanColumn(c).toLowerCase()))\n    .collect(Collectors.toSet());\nif (!missing.isEmpty() && !config.getDbMapping().isSkipMissing()) {\n    throw new IllegalStateException(\n        \"Target columns missing and skipMissing=false: \" + missing\n        + \" - set skipMissing:true or mapAll+alter:true\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    syncService.sync(batchExecutor, items);\n} catch (RuntimeException e) {\n    if (e.getMessage().contains(\"Target column:\") && e.getMessage().contains(\"not matched\")) {\n        logger.error(\"Schema drift: a target column is missing. \"\n            + \"Enable mapAll+alter or skipMissing, or add the column.\", e);\n    }\n    throw e;\n}","preventionTips":["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."],"tags":["phoenix","schema-drift","sync","canal","column-mapping"],"backgroundTag":null,"analyzedSha":"87be50e87686a3e8af08c368d0e1ffd1f59eb04a","analyzedAt":"2026-08-14T04:30:11.918Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}