keycloak/keycloak · error · ProfileException
Multiple versions of the same feature %s, %s should not be e
Error message
Multiple versions of the same feature %s, %s should not be enabled.
What it means
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.
Source
Thrown at common/src/main/java/org/keycloak/common/Profile.java:403
throw new ProfileException(String.format("Feature %s cannot be enabled as it is not available.", unversionedFeature));
}
} else if (unversionedConfig == FeatureConfig.DISABLED && ESSENTIAL_FEATURES.contains(unversionedFeature)) {
throw new ProfileException(String.format("Feature %s cannot be disabled.", unversionedFeature));
}
// now check each feature version to ensure consistency and select any features enabled by default
boolean isExplicitlyEnabledFeature = false;
for (Feature f : entry.getValue()) {
ProfileConfigResolver.FeatureConfig configuration = getFeatureConfig(f.getVersionedKey(), resolvers);
if (configuration != FeatureConfig.UNCONFIGURED && unversionedConfig != FeatureConfig.UNCONFIGURED) {
throw new ProfileException("Versioned feature " + f.getVersionedKey() + " is not expected as " + unversionedFeature + " is already " + unversionedConfig.name().toLowerCase());
}
switch (configuration) {
case ENABLED:
if (isExplicitlyEnabledFeature) {
throw new ProfileException(
String.format("Multiple versions of the same feature %s, %s should not be enabled.",
enabledFeature.getVersionedKey(), f.getVersionedKey()));
}
// even if something else was enabled by default, explicitly enabling a lower priority feature takes precedence
if (!f.isAvailable()) {
throw new ProfileException(String.format("Feature %s cannot be enabled as it is not available.", f.getVersionedKey()));
}
enabledFeature = f;
isExplicitlyEnabledFeature = true;
break;
case DISABLED:
throw new ProfileException("Feature " + f.getVersionedKey() + " should not be disabled using a versioned key.");
default:
if (unversionedConfig == FeatureConfig.UNCONFIGURED && enabledFeature == null
&& isEnabledByDefault(profile, f) && f.isAvailable()) {
enabledFeature = f;
}
break;View on GitHub (pinned to 66c7e15a37)
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.
Example fix
// before: two versions enabled kc.sh --features=account:v1,account:v3 // after: single version kc.sh --features=account:v3
Defensive patterns
Strategy: validation
Validate before calling
// Ensure only one version of each feature is enabled
Map<String, List<String>> byFeature = enabledVersions.stream()
.collect(Collectors.groupingBy(v -> v.split(":")[0]));
for (var entry : byFeature.entrySet()) {
if (entry.getValue().size() > 1) {
throw new IllegalStateException(
"Multiple versions enabled for " + entry.getKey() + ": " + entry.getValue());
}
} Prevention
- 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.
When it happens
Trigger: Setting -Dkeycloak.profile.feature.account:v1=enabled AND -Dkeycloak.profile.feature.account:v3=enabled simultaneously, or including both versioned keys in kc.features.
Common situations: 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.
Related errors
- Feature %s cannot be enabled as it is not available.
- Feature %s cannot be disabled.
- Versioned feature {} is not expected as {} is already {}
- Feature {} should not be disabled using a versioned key.
- Feature {} depends on disabled feature {}
AI-assisted analysis of keycloak/keycloak@66c7e15a37 (2026-08-14).
Data as JSON: /api/errors/7dcdb60550d93463.
Report an issue: GitHub.