SonarSource/sonarqube · error · IllegalStateException

Configuration error: property definition named

Error message

Configuration error: property definition named '%s' found in multiple extensions.

What it means

loadDefaultsFromExtensions collects default property values contributed by CoreExtension plugins via the service loader. If two extensions define the same property key, the configuration is ambiguous, so an IllegalStateException is thrown to fail fast at startup.

Solutions

  1. List the extensions directory and remove the duplicate/conflicting plugin jar.
  2. Identify which property key conflicts from the message and uninstall or upgrade one of the extensions defining it.
  3. If the conflict is intentional, merge the property definitions into a single extension or rename the key.

Example fix

// before
extensions/  my-plugin-1.0.jar  my-plugin-1.1.jar  // both define sonar.my.prop
// after
extensions/  my-plugin-1.1.jar  // only one version installed
Defensive patterns

Strategy: validation

Validate before calling

Map<String, String> seen = new HashMap<>();
for (CoreExtension ext : serviceLoaderWrapper.load()) {
  for (String key : ext.getExtensionProperties().keySet()) {
    if (seen.containsKey(key)) throw new IllegalStateException("Duplicate property " + key + " in " + seen.get(key) + " and " + ext);
    seen.put(key, ext.getClass().getName());
  }
}

Try / catch

try {
  props.completeDefaultsFromExtensions();
} catch (IllegalStateException e) {
  logger.error("Extension property conflict: {}", e.getMessage());
  System.exit(1);
}

Prevention

When it happens

Trigger: Installing two core extensions (plugins) whose getExtensionProperties() maps contain the same property key; the defaults() call during process bootstrap then detects the conflict.

Common situations: Deploying duplicate or overlapping plugin jars in the extensions directory; two forks of the same plugin both installed; a plugin update bundling properties another plugin already defines.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/0448fc818176b686. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-process/src/main/java/org/sonar/process/ProcessProperties.java:281

    }
  }

  private Properties defaults() {
    Properties defaults = new Properties();
    defaults.putAll(Arrays.stream(Property.values())
      .filter(Property::hasDefaultValue)
      .collect(Collectors.toMap(Property::getKey, Property::getDefaultValue)));
    defaults.putAll(loadDefaultsFromExtensions());
    return defaults;
  }

  private Map<String, String> loadDefaultsFromExtensions() {
    Map<String, String> propertyDefaults = new HashMap<>();
    Set<CoreExtension> extensions = serviceLoaderWrapper.load();
    for (CoreExtension ext : extensions) {
      for (Map.Entry<String, String> property : ext.getExtensionProperties().entrySet()) {
        if (propertyDefaults.put(property.getKey(), property.getValue()) != null) {
          throw new IllegalStateException(format("Configuration error: property definition named '%s' found in multiple extensions.",
            property.getKey()));
        }
      }
    }

    return propertyDefaults;
  }

  private static void fixPortIfZero(Props props, String addressPropertyKey, String portPropertyKey) {
    String port = props.value(portPropertyKey);
    if ("0".equals(port)) {
      String address = props.nonNullValue(addressPropertyKey);
      int allocatedPort = NetworkUtilsImpl.INSTANCE.getNextAvailablePort(address)
        .orElseThrow(() -> new IllegalStateException("Cannot resolve address [" + address + "] set by property [" + addressPropertyKey + "]"));
      props.set(portPropertyKey, String.valueOf(allocatedPort));
    }
  }

View on GitHub (pinned to 184c821202)