apache/cassandra · error
Config contains both old and new keys for the same…
Error message
Config contains both old and new keys for the same configuration parameters, migrate old -> new: %s
What it means
Cassandra renamed many cassandra.yaml keys (old snake_case or legacy names replaced by new canonical ones). YamlConfigurationLoader.verifyReplacements() detects when both the old and the new key for the same parameter appear in the config, which is ambiguous. Unless the flag cassandra.allow_new_old_config_keys is set, it throws ConfigurationException and refuses to start; otherwise it logs this warning.
Solutions
- Remove the old key(s) and keep only the new canonical name listed in the message
- If temporarily unavoidable, start with -Dcassandra.allow_new_old_config_keys=true to downgrade to a warning, then migrate promptly
- Check conf/yaml aliases for the version to map each old key to its replacement
Example fix
// cassandra.yaml before commitlog_sync_period_in_ms: 10000 commitlog_sync_period: 10000ms // after commitlog_sync_period: 10000ms
Defensive patterns
Strategy: try-catch
Validate before calling
// diff config against the version's allowed keys before deploy
Set<String> allowed = allowedKeysForVersion(targetVersion);
Set<String> present = readTopLevelYamlKeys(Path.of("conf/cassandra.yaml"));
Set<String> stale = new HashSet<>(present); stale.removeAll(allowed);
if (!stale.isEmpty()) throw new IllegalStateException("Remove old keys: " + stale); Try / catch
try { DatabaseDescriptor.daemonInitialization(); } catch (ConfigurationException e) { if (e.getMessage().contains("migrate old -> new")) { /* fix yaml keys, restart */ } throw e; } Prevention
- Only allow one name per parameter in yaml templates
- Run config lint against the target Cassandra version's replacement map in CI
- Avoid layering templates from different Cassandra versions in config management
- Never rely on cassandra.allow_new_old_config_keys in production
When it happens
Trigger: cassandra.yaml contains e.g. both commitlog_sync_period_in_ms and commitlog_sync_period (old+new pair) for any renamed parameter; raised during loadConfig -> verifyReplacements at startup or config reload. Setting -Dcassandra.allow_new_old_config_keys=true downgrades to a warning.
Common situations: Upgrades where tools merge old and new yaml templates; copy-pasting snippets from both old and new documentation; config management systems (Puppet/Ansible) layering templates from different Cassandra versions.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Configuration entry can not inherit itself.
- Configuration entry inherits non-existing entry .
- data_file_directories must not contain empty entry
- Detected loop when processing key
- memtable_cleanup_threshold has been deprecated and should…
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/b5385b60302e6372.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/config/YamlConfigurationLoader.java:312
{
for (Map.Entry<String, Replacement> entry : outerEntry.getValue().entrySet())
{
Replacement r = entry.getValue();
if (!r.isValueFormatReplacement() && rawConfig.containsKey(r.oldName) && rawConfig.containsKey(r.newName))
{
String msg = String.format("[%s -> %s]", r.oldName, r.newName);
duplicates.add(msg);
}
}
}
if (!duplicates.isEmpty())
{
String msg = String.format("Config contains both old and new keys for the same configuration parameters, migrate old -> new: %s", String.join(", ", duplicates));
if (!ALLOW_NEW_OLD_CONFIG_KEYS.getBoolean())
throw new ConfigurationException(msg);
else
logger.warn(msg);
}
}
private static void verifyReplacements(Map<Class<?>, Map<String, Replacement>> replacements, byte[] configBytes)
{
LoaderOptions loaderOptions = getDefaultLoaderOptions();
loaderOptions.setAllowDuplicateKeys(ALLOW_DUPLICATE_CONFIG_KEYS.getBoolean());
Yaml rawYaml = new Yaml(loaderOptions);
Map<String, Object> rawConfig = rawYaml.load(new ByteArrayInputStream(configBytes));
if (rawConfig == null)
rawConfig = new HashMap<>();
verifyReplacements(replacements, rawConfig);
}
@VisibleForTesting
public static <T> T fromMap(Map<String,Object> map, Class<T> klass)View on GitHub (pinned to 88fd0f6a0e)