apache/maven · critical · IllegalArgumentException

Found duplicated phase '{}' in '{}' lifecycle

Error message

Found duplicated phase '{}' in '{}' lifecycle

What it means

IllegalArgumentException thrown from DefaultLifecycleRegistry's constructor while validating every registered lifecycle: within a single lifecycle, a phase name may appear only once. Because this fires during Sisu component wiring at container startup, a duplicate poisons the whole container — Maven fails before any project builds.

Source

Thrown at impl/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultLifecycleRegistry.java:118

    public static final String SCOPE_TEST = DependencyScope.TEST.id();

    private final List<LifecycleProvider> providers;

    public DefaultLifecycleRegistry() {
        this(Collections.emptyList());
    }

    @Inject
    public DefaultLifecycleRegistry(List<LifecycleProvider> providers) {
        List<LifecycleProvider> p = new ArrayList<>(providers);
        p.add(() -> List.of(new CleanLifecycle(), new DefaultLifecycle(), new SiteLifecycle()));
        this.providers = p;
        // validate lifecycle
        for (Lifecycle lifecycle : this) {
            Set<String> set = new HashSet<>();
            lifecycle.allPhases().forEach(phase -> {
                if (!set.add(phase.name())) {
                    throw new IllegalArgumentException(
                            "Found duplicated phase '" + phase.name() + "' in '" + lifecycle.id() + "' lifecycle");
                }
            });
        }
    }

    static String getImplementationVersion(Class<?> clazz) {
        Package packageInfo = clazz.getPackage();
        return packageInfo != null ? packageInfo.getImplementationVersion() : null;
    }

    @Override
    public Iterator<Lifecycle> iterator() {
        return stream().toList().iterator();
    }

    @Override
    public Stream<Lifecycle> stream() {

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Open the failing lifecycle (its id is in the message); in the contributing plugin's lifecycle mapping, remove or rename the duplicated phase
  2. Reference built-in phases instead of re-declaring them in a custom lifecycle
  3. Pin or upgrade the plugin that contributes the custom lifecycle to a version built for the Maven version in use
Defensive patterns

Strategy: validation

Validate before calling

// Validate a custom lifecycle definition before contributing it
Set<String> seen = new HashSet<>();
for (Phase phase : customLifecycle.allPhases()) {
    if (!seen.add(phase.name())) {
        throw new IllegalArgumentException(
            "duplicate phase '" + phase.name() + "' in lifecycle " + customLifecycle.id());
    }
}

Prevention

When it happens

Trigger: A LifecycleProvider (typically a plugin contributing custom packaging/lifecycles via its descriptor's lifecycle mappings) returns phases whose name() duplicates another phase in the same lifecycle id — e.g. a custom packaging re-declaring 'compile' or copying the default lifecycle's phases into its own list.

Common situations: Custom packaging plugins with hand-written lifecycle definitions; upgrading Maven major versions where provider APIs changed and previously-shadowed mappings now collide with built-in lifecycles (default, clean, site).

Related errors


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