apache/maven · error · DuplicateProjectException

Project '{}' is duplicated in the reactor

Error message

Project '{}' is duplicated in the reactor

What it means

ProjectSorter turns a multi-module build's project list into a DAG for reactor ordering. It keys every module by its full coordinates groupId:artifactId:version and throws DuplicateProjectException when a second project maps to the same id, because one GAV must identify exactly one vertex in the graph.

Source

Thrown at impl/maven-core/src/main/java/org/apache/maven/project/ProjectSorter.java:84

    // In this case, both the verify and the report goals are called
    // in a different lifecycle. Though the compiler-plugin has a valid use case, although
    // that seems to work fine. We need to take versions and lifecycle into account.
    public ProjectSorter(Collection<MavenProject> projects) throws CycleDetectedException, DuplicateProjectException {
        graph = new Graph();

        // groupId:artifactId:version -> project
        projectMap = new HashMap<>(projects.size() * 2);

        // groupId:artifactId -> (version -> vertex)
        Map<String, Map<String, Vertex>> vertexMap = new HashMap<>(projects.size() * 2);

        for (MavenProject project : projects) {
            String projectId = getId(project);

            MavenProject conflictingProject = projectMap.put(projectId, project);

            if (conflictingProject != null) {
                throw new DuplicateProjectException(
                        projectId,
                        conflictingProject.getFile(),
                        project.getFile(),
                        "Project '" + projectId + "' is duplicated in the reactor");
            }

            String projectKey = ArtifactUtils.versionlessKey(project.getGroupId(), project.getArtifactId());

            Map<String, Vertex> vertices = vertexMap.computeIfAbsent(projectKey, k -> new HashMap<>(2, 1));

            vertices.put(project.getVersion(), graph.addVertex(projectId));
        }

        for (Vertex projectVertex : graph.getVertices()) {
            String projectId = projectVertex.getLabel();

            MavenProject project = projectMap.get(projectId);

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Read the projectId named in the exception (groupId:artifactId:version) and grep all pom.xml files for that artifactId to locate the colliding modules
  2. Give each colliding module a unique <artifactId> or a different <version>
  3. Remove the duplicated <module> entry or the profile inclusion that adds the same project twice
  4. If the same project must feed several builds, build it once and consume it as a normal dependency

Example fix

<!-- before -->
<modules>
  <module>api</module>
  <module>api</module>   <!-- duplicated entry -->
  <module>app</module>
</modules>

<!-- after -->
<modules>
  <module>api</module>
  <module>app</module>
</modules>
Defensive patterns

Strategy: try-catch

Validate before calling

Map<String, MavenProject> seen = new HashMap<>();
for (MavenProject p : projects) {
    String id = p.getGroupId() + ":" + p.getArtifactId() + ":" + p.getVersion();
    if (seen.put(id, p) != null) {
        throw new IllegalArgumentException("Duplicate reactor project: " + id);
    }
}
new ProjectSorter(projects);

Try / catch

try {
    ProjectSorter sorter = new ProjectSorter(projects);
} catch (DuplicateProjectException e) {
    // e.getProjectId() names the colliding groupId:artifactId:version
    throw new BuildFailure("duplicate module " + e.getProjectId(), e);
}

Prevention

When it happens

Trigger: Calling new ProjectSorter(projects) (directly or via reactor/session setup) with two MavenProject instances sharing groupId, artifactId and version: the same module directory listed twice in <modules>, or two different directories whose POMs declare identical coordinates.

Common situations: Copy-pasted module POMs where <artifactId> was never changed; the same module included by both the parent <modules> list and an active profile; aggregate POMs re-including an already-built submodule; version overrides that make two modules collide.

Related errors


AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21). Data as JSON: /api/errors/fe6853db5df28ee6. Report an issue: GitHub.