alibaba/canal · critical · RuntimeException
No kudu adapter found for config key: {}
Error message
No kudu adapter found for config key: {} What it means
Thrown by KuduAdapter.init() after it loads every kudu mapping yml and filters each through addConfig()->match(). If none of the loaded configs match this adapter's key, kuduMapping stays empty and the adapter aborts startup rather than run with nothing to sync. The thrown key is configuration.getKey(), the 'key:' declared for this adapter under canalAdapters in application.yml.
Source
Thrown at client-adapter/kudu/src/main/java/com/alibaba/otter/canal/client/adapter/kudu/KuduAdapter.java:67
return kuduMapping;
}
public Map<String, Map<String, KuduMappingConfig>> getMappingConfigCache() {
return mappingConfigCache;
}
@Override
public void init(OuterAdapterConfig configuration, Properties envProperties) {
this.envProperties = envProperties;
this.configuration = configuration;
Map<String, KuduMappingConfig> kuduMappingTmp = KuduMappingConfigLoader.load(envProperties);
// 过滤不匹配的key的配置,获取连接key,key为配置文件名称
kuduMappingTmp.forEach((key, config) -> {
addConfig(key, config);
});
// 判断目标字段是否为空
if (kuduMapping.isEmpty()) {
throw new RuntimeException("No kudu adapter found for config key: " + configuration.getKey());
}
Map<String, String> properties = configuration.getProperties();
String kudu_master = properties.get("kudu.master.address");
kuduTemplate = new KuduTemplate(kudu_master);
kuduSyncService = new KuduSyncService(kuduTemplate);
kuduConfigMonitor = new KuduConfigMonitor();
kuduConfigMonitor.init(this, envProperties);
}
@Override
public void sync(List<Dml> dmls) {
if (dmls == null || dmls.isEmpty()) {
return;
}
for (Dml dml : dmls) {View on GitHub (pinned to 87be50e876)
Solutions
- Open application.yml, find the kudu entry under canalAdapters[*].groups[*].outerAdapters, note its 'key:' value, and set 'outerAdapterKey:' in every kudu/*.yml to exactly that value (match is case-insensitive).
- Confirm the kudu mapping yml files live in the directory MappingConfigsLoader scans for the "kudu" adapter name and are valid YAML.
- Check startup logs: if '## kudu mapping config loaded' prints but the error still fires, the keys mismatch; if it never prints, loading failed entirely.
- Remove stray whitespace/quotes around outerAdapterKey values in both files.
Example fix
# application.yml
canalAdapters:
- instance: example
groups:
- groupId: g1
outerAdapters:
- name: kudu
key: kudu # <-- adapter key
# kudu/my_table.yml
outerAdapterKey: kudu # <-- must equal the key above Defensive patterns
Strategy: validation
Validate before calling
// Before starting the kudu adapter, assert at least one
// loaded config matches the adapter key.
String adapterKey = configuration.getKey(); // e.g. "kudu"
boolean anyMatch = KuduMappingConfigLoader.load(envProperties)
.values().stream()
.anyMatch(c -> c.getOuterAdapterKey() != null
&& c.getOuterAdapterKey().equalsIgnoreCase(adapterKey));
if (!anyMatch) {
throw new IllegalStateException(
"No kudu mapping yml has outerAdapterKey=" + adapterKey
+ " - fix application.yml key or the yml before init");
} Prevention
- Keep adapter 'key:' in application.yml and 'outerAdapterKey:' in every mapping yml in a single shared variable/config so they cannot diverge.
- Add a startup smoke test that loads all mapping yml files and asserts each declared adapter key has >=1 matching config.
- Treat an empty KuduMappingConfigLoader result as a configuration error in CI, not a silent skip.
When it happens
Trigger: KuduAdapter.init() runs; for every loaded KuduMappingConfig, match() returns false because outerAdapterKey is non-null and not equalsIgnoreCase(configuration.getKey()), OR outerAdapterKey is null and configuration.getKey() does not start with the auto-generated prefix built from destination+groupId. Alternatively KuduMappingConfigLoader.load() returned an empty map (no files in the kudu config dir, or every file parsed to null).
Common situations: The 'outerAdapterKey:' line in a kudu/*.yml file does not match the 'key:' of the kudu adapter entry in application.yml (e.g. yml says 'outerAdapterKey: kudu1' but application.yml declares 'key: kudu'). Mapping yml files placed in the wrong directory so MappingConfigsLoader.loadConfigs("kudu") finds none. A YAML syntax error causes YamlUtils.ymlToObj to return null, which the loader silently skips, emptying the map.
Related errors
- No phoenix adapter found for config key: {}
- No rdb adapter found for config key: {key}
- not allow to change outAdapterKey
- KuduMapping.database
- ERROR load Config: {} {}
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/3452360844edd965.
Report an issue: GitHub.