{"record":{"id":"ed03dfcc32708570","repo":"apache/cassandra","slug":"config-contains-both-old-and-new-keys-for-the-same","errorCode":null,"errorMessage":"Config contains both old and new keys for the same configuration parameters, migrate old -> new: <duplicates>","messagePattern":"Config contains both old and new keys for the same configuration parameters, migrate old -> new: <duplicates>","errorType":"validation","errorClass":"ConfigurationException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/config/YamlConfigurationLoader.java","lineNumber":310,"sourceCode":"        List<String> duplicates = new ArrayList<>();\n        for (Map.Entry<Class<?>, Map<String, Replacement>> outerEntry : replacements.entrySet())\n        {\n            for (Map.Entry<String, Replacement> entry : outerEntry.getValue().entrySet())\n            {\n                Replacement r = entry.getValue();\n                if (!r.isValueFormatReplacement() && rawConfig.containsKey(r.oldName) && rawConfig.containsKey(r.newName))\n                {\n                    String msg = String.format(\"[%s -> %s]\", r.oldName, r.newName);\n                    duplicates.add(msg);\n                }\n            }\n        }\n\n        if (!duplicates.isEmpty())\n        {\n            String msg = String.format(\"Config contains both old and new keys for the same configuration parameters, migrate old -> new: %s\", String.join(\", \", duplicates));\n            if (!ALLOW_NEW_OLD_CONFIG_KEYS.getBoolean())\n                throw new ConfigurationException(msg);\n            else\n                logger.warn(msg);\n        }\n    }\n\n    private static void verifyReplacements(Map<Class<?>, Map<String, Replacement>> replacements, byte[] configBytes)\n    {\n        LoaderOptions loaderOptions = getDefaultLoaderOptions();\n        loaderOptions.setAllowDuplicateKeys(ALLOW_DUPLICATE_CONFIG_KEYS.getBoolean());\n        Yaml rawYaml = new Yaml(loaderOptions);\n\n        Map<String, Object> rawConfig = rawYaml.load(new ByteArrayInputStream(configBytes));\n        if (rawConfig == null)\n            rawConfig = new HashMap<>();\n        verifyReplacements(replacements, rawConfig);\n\n    }\n","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/config/YamlConfigurationLoader.java#L292-L328","documentation":"During config load, Cassandra detects that the yaml contains both a deprecated/old key and its renamed (new) equivalent for the same parameter. Because it cannot decide which value wins, it throws unless the flag cassandra.allow_new_old_config_keys (ALLOW_NEW_OLD_CONFIG_KEYS) is set, in which case it only logs a warning. This enforces migration to the new unified key names.","triggerScenarios":"loadConfig -> verifyReplacements finding e.g. both 'commitlog_sync_period_in_ms' and its replacement in the same yaml; also reachable via fromMap/updateFromMap when programmatically updating Config with both spellings; thrown only when the boolean config ALLOW_NEW_OLD_CONFIG_KEYS is false (default).","commonSituations":"Upgrading from Cassandra 4.x to 5.x without migrating renamed config keys; merge conflicts or sed scripts that appended new keys while leaving old ones; documentation referencing old names.","solutions":["Remove the old key and keep only the new (renamed) key in cassandra.yaml","Check NEWS.txt / the Replacement-annotated Config fields for the old->new mapping of the listed duplicate keys","Temporarily set the system property cassandra.allow_new_old_config_keys=true to warn instead of fail while migrating (not a permanent fix)","Search the yaml for each key named in the message and delete the deprecated occurrence"],"exampleFix":"// before (cassandra.yaml)\nhinted_handoff_enabled: true\nmax_hint_window_in_ms: 10800000\nhinted_handoff_throttle_in_kb: 1024\n// after (migrate old -> new)\nhinted_handoff_enabled: true\nmax_hint_window: 10800000ms\nhinted_handoff_throttle: 1024KiB","handlingStrategy":"validation","validationCode":"// fail startup early if both old and new keys appear\nString yaml = java.nio.file.Files.readString(Path.of(\"cassandra.yaml\"));\nList<String> pairs = List.of(\"max_hint_window_in_ms:max_hint_window\");\nfor (String p : pairs) {\n    var parts = p.split(\":\");\n    if (yaml.contains(parts[0]) && yaml.contains(parts[1]))\n        throw new IllegalStateException(\"Both old and new key present: \" + p);\n}","typeGuard":null,"tryCatchPattern":"try {\n    config = loader.loadConfig(url);\n} catch (ConfigurationException e) {\n    if (e.getMessage().startsWith(\"Config contains both old and new keys\"))\n        log.error(\"Migrate deprecated keys per NEWS.txt: \" + e.getMessage());\n    throw e;\n}","preventionTips":["Migrate to new key names immediately after each major upgrade","Keep only one spelling per parameter in cassandra.yaml","Grep yaml for *_in_ms legacy names during upgrade runbooks","Read NEWS.txt upgrade notes before rolling new versions"],"tags":["configuration","deprecation","migration"],"backgroundTag":"conflicting-config-options","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}