alibaba/canal · error · RuntimeException
not allow to change outAdapterKey
Error message
not allow to change outAdapterKey
What it means
Thrown by ClickHouseAdapter.updateConfig during hot config reload. The new config's outerAdapterKey differs from the adapter's own configuration.getKey(). outerAdapterKey is the immutable binding between a mapping config and its adapter instance; changing it at runtime would orphan the config from its adapter, so it is forbidden.
Source
Thrown at client-adapter/clickhouse/src/main/java/com/alibaba/otter/canal/client/adapter/clickhouse/ClickHouseAdapter.java:315
}
}
public boolean addConfig(String fileName, MappingConfig config) {
if (match(config)) {
clickHouseMapping.put(fileName, config);
addSyncConfigToCache(fileName, config);
FileName2KeyMapping.register(getClass().getAnnotation(SPI.class).value(), fileName,
configuration.getKey());
return true;
}
return false;
}
public void updateConfig(String fileName, MappingConfig config) {
if (config.getOuterAdapterKey() != null && !config.getOuterAdapterKey()
.equals(configuration.getKey())) {
// 理论上不允许改这个 因为本身就是通过这个关联起Adapter和Config的
throw new RuntimeException("not allow to change outAdapterKey");
}
clickHouseMapping.put(fileName, config);
addSyncConfigToCache(fileName, config);
}
public void deleteConfig(String fileName) {
clickHouseMapping.remove(fileName);
for (Map<String, MappingConfig> configMap : mappingConfigCache.values()) {
if (configMap != null) {
configMap.remove(fileName);
}
}
FileName2KeyMapping.unregister(getClass().getAnnotation(SPI.class).value(), fileName);
}
private boolean match(MappingConfig config) {
boolean sameMatch = config.getOuterAdapterKey() != null && config.getOuterAdapterKey()
.equalsIgnoreCase(configuration.getKey());View on GitHub (pinned to 87be50e876)
Solutions
- Keep outerAdapterKey stable across hot edits; do not change it on a running adapter.
- To repoint a config to a different adapter, delete it from this adapter and add it to the target adapter instead.
- If the key truly changed intentionally, restart the adapter rather than relying on hot reload.
- Audit config-management/CI outputs to ensure outerAdapterKey is not rewritten.
Example fix
# before (hot edit changes the key): # outerAdapterKey: clickhouse-2 <- was clickhouse-1 # after (keep the key, restart to repoint): # leave outerAdapterKey: clickhouse-1 unchanged in the file; # to repoint, stop adapter, move file, restart with the new adapter.
Defensive patterns
Strategy: validation
Validate before calling
// In a pre-commit/CI check on hot-reloaded config files, forbid outerAdapterKey changes:
String oldKey = existingConfig.getOuterAdapterKey();
String newKey = incomingConfig.getOuterAdapterKey();
if (oldKey != null && newKey != null && !oldKey.equals(newKey)) {
throw new IllegalStateException("Refusing to change outerAdapterKey (" + oldKey + " -> " + newKey + "); restart to repoint.");
} Try / catch
try {
adapter.updateConfig(fileName, newConfig);
} catch (RuntimeException e) {
if (e.getMessage().contains("not allow to change outAdapterKey")) {
logger.error("Hot edit changed outerAdapterKey in {}; revert or restart the adapter.", fileName);
}
throw e;
} Prevention
- Never edit outerAdapterKey on a running adapter via hot reload.
- To repoint a config, stop the adapter, move/update the file, then restart.
- Audit config-management tools so they do not rewrite outerAdapterKey.
- Keep outerAdapterKey consistent across versions of a mapping file.
When it happens
Trigger: The ClickHouseConfigMonitor detects a changed mapping file and calls updateConfig, but the edited file's outerAdapterKey was changed to a different adapter key; editing the yml's outerAdapterKey field while the adapter is running.
Common situations: Operator edits a hot-reloaded mapping file and changes outerAdapterKey to repoint it to another adapter; copy-pasting a config from one adapter to another without fixing the key; misconfigured config-management tooling that rewrites keys.
Related errors
- No clickhouse adapter found for config key: {}
- ERROR Config: {} {}
- dbMapping.database
- dbMapping.table
- dbMapping.targetTable
AI-assisted analysis of alibaba/canal@87be50e876 (2026-08-14).
Data as JSON: /api/errors/663f5b5a4ca434e6.
Report an issue: GitHub.