{"record":{"id":"7dcdb60550d93463","repo":"keycloak/keycloak","slug":"multiple-versions-of-the-same-feature-s-s-shoul","errorCode":null,"errorMessage":"Multiple versions of the same feature %s, %s should not be enabled.","messagePattern":"Multiple versions of the same feature (.+?), (.+?) should not be enabled\\.","errorType":"exception","errorClass":"ProfileException","httpStatus":null,"severity":"error","filePath":"common/src/main/java/org/keycloak/common/Profile.java","lineNumber":403,"sourceCode":"                    throw new ProfileException(String.format(\"Feature %s cannot be enabled as it is not available.\", unversionedFeature));\n                }\n            } else if (unversionedConfig == FeatureConfig.DISABLED && ESSENTIAL_FEATURES.contains(unversionedFeature)) {\n                throw new ProfileException(String.format(\"Feature %s cannot be disabled.\", unversionedFeature));\n            }\n\n            // now check each feature version to ensure consistency and select any features enabled by default\n            boolean isExplicitlyEnabledFeature = false;\n            for (Feature f : entry.getValue()) {\n                ProfileConfigResolver.FeatureConfig configuration = getFeatureConfig(f.getVersionedKey(), resolvers);\n\n                if (configuration != FeatureConfig.UNCONFIGURED && unversionedConfig != FeatureConfig.UNCONFIGURED) {\n                    throw new ProfileException(\"Versioned feature \" + f.getVersionedKey() + \" is not expected as \" + unversionedFeature + \" is already \" + unversionedConfig.name().toLowerCase());\n                }\n\n                switch (configuration) {\n                case ENABLED:\n                    if (isExplicitlyEnabledFeature) {\n                        throw new ProfileException(\n                                String.format(\"Multiple versions of the same feature %s, %s should not be enabled.\",\n                                        enabledFeature.getVersionedKey(), f.getVersionedKey()));\n                    }\n                    // even if something else was enabled by default, explicitly enabling a lower priority feature takes precedence\n                    if (!f.isAvailable()) {\n                        throw new ProfileException(String.format(\"Feature %s cannot be enabled as it is not available.\", f.getVersionedKey()));\n                    }\n                    enabledFeature = f;\n                    isExplicitlyEnabledFeature = true;\n                    break;\n                case DISABLED:\n                    throw new ProfileException(\"Feature \" + f.getVersionedKey() + \" should not be disabled using a versioned key.\");\n                default:\n                    if (unversionedConfig == FeatureConfig.UNCONFIGURED && enabledFeature == null\n                            && isEnabledByDefault(profile, f) && f.isAvailable()) {\n                        enabledFeature = f;\n                    }\n                    break;","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/keycloak/keycloak/blob/66c7e15a3788de7764f07dd2558275a02770e16d/common/src/main/java/org/keycloak/common/Profile.java#L385-L421","documentation":"Thrown during Profile.configure() when two different versions of the same feature are both explicitly enabled. For example, enabling both account:v1 and account:v3. Keycloak allows only one version of a feature to be active at a time. The exception reports both conflicting versioned keys.","triggerScenarios":"Setting -Dkeycloak.profile.feature.account:v1=enabled AND -Dkeycloak.profile.feature.account:v3=enabled simultaneously, or including both versioned keys in kc.features.","commonSituations":"Transitioning between feature versions and leaving the old version enabled; configuration management tools (Ansible, Helm) layering multiple feature flags; misunderstanding that only one version can be active.","solutions":["Enable only one version of the feature — choose either the old or the new version.","Remove the conflicting version from your feature configuration.","If migrating, disable the old version before enabling the new one."],"exampleFix":"// before: two versions enabled\nkc.sh --features=account:v1,account:v3\n// after: single version\nkc.sh --features=account:v3","handlingStrategy":"validation","validationCode":"// Ensure only one version of each feature is enabled\nMap<String, List<String>> byFeature = enabledVersions.stream()\n    .collect(Collectors.groupingBy(v -> v.split(\":\")[0]));\nfor (var entry : byFeature.entrySet()) {\n    if (entry.getValue().size() > 1) {\n        throw new IllegalStateException(\n            \"Multiple versions enabled for \" + entry.getKey() + \": \" + entry.getValue());\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enable only one version of each feature.","During version migrations, disable the old version before enabling the new one.","Use configuration validation scripts to detect multi-version conflicts."],"tags":["keycloak","profile","feature-management","configuration","version-conflict"],"backgroundTag":null,"analyzedSha":"66c7e15a3788de7764f07dd2558275a02770e16d","analyzedAt":"2026-08-14T01:36:42.651Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}