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

  1. Keep outerAdapterKey stable across hot edits; do not change it on a running adapter.
  2. To repoint a config to a different adapter, delete it from this adapter and add it to the target adapter instead.
  3. If the key truly changed intentionally, restart the adapter rather than relying on hot reload.
  4. 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

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


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