apache/maven · error · Exception
%nThere can only be one user supplied ConfigurationProcessor
Error message
%nThere can only be one user supplied ConfigurationProcessor, there are %s:%n%n
What it means
During CLI configuration, Maven scans the (Plexus/JSR-330) container for ConfigurationProcessor components. Exactly one non-default processor may exist besides the built-in 'settingsxml' one (SettingsXmlConfigurationProcessor). If two or more user-supplied processors are discovered, Maven cannot decide which to run and throws a plain Exception whose message counts them and lists each offending implementation class name. This only happens when embedding MavenCli or assembling a custom Maven distribution — a stock mvn install has exactly one.
Source
Thrown at compat/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java:1229
configurationProcessor.process(cliRequest);
}
}
} else if (userSuppliedConfigurationProcessorCount > 1) {
//
// There are too many ConfigurationProcessors so we don't know which one to run so report the error.
//
StringBuilder sb = new StringBuilder(String.format(
"%nThere can only be one user supplied ConfigurationProcessor, there are %s:%n%n",
userSuppliedConfigurationProcessorCount));
for (Entry<String, ConfigurationProcessor> entry : configurationProcessors.entrySet()) {
String hint = entry.getKey();
if (!hint.equals(SettingsXmlConfigurationProcessor.HINT)) {
ConfigurationProcessor configurationProcessor = entry.getValue();
sb.append(String.format(
"%s%n", configurationProcessor.getClass().getName()));
}
}
throw new Exception(sb.toString());
}
}
void toolchains(CliRequest cliRequest) throws Exception {
File userToolchainsFile = null;
if (cliRequest.commandLine.hasOption(CLIManager.ALTERNATE_USER_TOOLCHAINS)) {
userToolchainsFile = new File(cliRequest.commandLine.getOptionValue(CLIManager.ALTERNATE_USER_TOOLCHAINS));
userToolchainsFile = ResolveFile.resolveFile(userToolchainsFile, cliRequest.workingDirectory);
if (!userToolchainsFile.isFile()) {
throw new FileNotFoundException(
"The specified user toolchains file does not exist: " + userToolchainsFile);
}
} else {
String userToolchainsFileStr = cliRequest.getUserProperties().getProperty(Constants.MAVEN_USER_TOOLCHAINS);
if (userToolchainsFileStr != null) {
userToolchainsFile = new File(userToolchainsFileStr);View on GitHub (pinned to e4093d4e12)
Solutions
- Read the class names listed in the exception message; identify which jar ships each one.
- Remove or exclude the extra implementation (Maven dependency exclusion, or delete the duplicate jar from the distribution's lib directory).
- If both processors are needed, consolidate them into a single implementation that chains the logic, keeping one component.
- Verify classpath hygiene: mvn dependency:tree in the embedding project or unzip -l the suspect jars to confirm exactly one ConfigurationProcessor remains.
Example fix
<!-- before: two processors on classpath -->
<dependency>
<groupId>corp</groupId><artifactId>corp-maven-processor</artifactId>
</dependency>
<dependency>
<groupId>vendor</groupId><artifactId>vendor-build-extensions</artifactId>
<!-- also contains a ConfigurationProcessor -->
</dependency>
<!-- after: exclude the duplicate -->
<dependency>
<groupId>vendor</groupId><artifactId>vendor-build-extensions</artifactId>
<exclusions>
<exclusion>
<groupId>vendor</groupId><artifactId>vendor-processor</artifactId>
</exclusion>
</exclusions>
</dependency> Defensive patterns
Strategy: validation
Validate before calling
// Embedder startup check before MavenCli.doMain
List<ConfigurationProcessor> processors = container.lookupList(ConfigurationProcessor.class);
long userSupplied = processors.stream()
.filter(p -> !SettingsXmlConfigurationProcessor.HINT.equals(roleHintOf(p)))
.count();
if (userSupplied > 1) {
throw new IllegalStateException("Multiple ConfigurationProcessors on classpath: "
+ processors.stream().map(p -> p.getClass().getName()).collect(Collectors.joining(", ")));
} Try / catch
try {
cli.doMain(args, ...);
} catch (Exception e) {
if (e.getMessage() != null && e.getMessage().contains("There can only be one user supplied ConfigurationProcessor")) {
// parse listed class names, fail with actionable guidance for the distribution owner
}
throw e;
} Prevention
- In embedding projects, add a test that asserts exactly one non-default ConfigurationProcessor is discovered on the runtime classpath.
- Review dependency trees before adding integrator jars to a custom distribution; exclude duplicate components explicitly.
- Never bundle two versions of the same processor jar; let Maven's lib directory contain a single copy.
When it happens
Trigger: Launching MavenCli/MavenCliRequest programmatically with a classpath containing two ConfigurationProcessor implementations (each registered via Plexus component descriptors or javax.inject @Named). Adding a custom processor project while a third-party dependency (another extension or integrator jar) already ships one. Two versions of the same processor jar ending up on the classpath.
Common situations: Companies embedding Maven in build services/IDEs adding their own ConfigurationProcessor, then pulling a dependency that also contains one. Custom Maven distributions (tarballs with extra libs in lib/) that accidentally bundle both a processor and a fat jar embedding another. Duplicate classes after shading/merging jars.
Related errors
- Cannot read metadata from '{}'
- Unable to lookup org.eclipse.aether.RepositorySystem
- Error in component graph of plugin ${plugin.getId()}: ${e.ge
- Unable to load the mojo '${mojoDescriptor.getGoal()}' (or on
- The version cannot be empty.
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/80d1a9f02b1b41ab.
Report an issue: GitHub.