apache/maven · warning

The consumer POM for {} cannot be downgraded to 4.0.0. If yo

Error message

The consumer POM for {} cannot be downgraded to 4.0.0. If you intent your build to be consumed with Maven 3 projects, you need to remove the features that request a newer model version.  If you're fine with having the consumer POM not consumable with Maven 3, add the `preserve.model.version='true'` attribute on the <project> element of your POM.

What it means

Maven 4 generates a consumer POM (the flattened POM that gets installed/deployed) downgraded to modelVersion 4.0.0 so Maven 3 consumers can read it. warnNotDowngraded fires when the project's model uses features that require a newer model version, making a 4.0.0 downgrade impossible: the consumer POM keeps the newer model version, and Maven 3 clients fail to parse it.

Source

Thrown at impl/maven-core/src/main/java/org/apache/maven/internal/transformation/impl/DefaultConsumerPomBuilder.java:447

        if (!preserveModelVersion) {
            /*
             * If the <build> contains <source> elements, it is not compatible with the Maven 4.0.0 model.
             * Remove the full <build> element instead of removing only the <sources> element, because the
             * build without sources does not mean much. Reminder: this removal can be disabled by setting
             * the `preserveModelVersion` XML attribute or `preserve.model.version` property to true.
             */
            if (SourceQueries.hasEnabledSources(projectSources)) {
                model = model.withBuild(null);
            }
            model = model.withPreserveModelVersion(false);
            String modelVersion = new MavenModelVersion().getModelVersion(model);
            model = model.withModelVersion(modelVersion);
        }
        return model;
    }

    private static void warnNotDowngraded(MavenProject project) {
        LOGGER.warn("The consumer POM for " + project.getId() + " cannot be downgraded to 4.0.0. "
                + "If you intent your build to be consumed with Maven 3 projects, you need to remove "
                + "the features that request a newer model version.  If you're fine with having the "
                + "consumer POM not consumable with Maven 3, add the `preserve.model.version='true'` "
                + "attribute on the <project> element of your POM.");
    }

    private static List<Profile> prune(List<Profile> profiles) {
        return profiles.stream()
                .map(p -> {
                    Profile.Builder builder = Profile.newBuilder(p, true);
                    prune((ModelBase.Builder) builder, p);
                    return builder.build(null).build();
                })
                .filter(p -> !isEmpty(p))
                .collect(Collectors.toList());
    }

    private static boolean isEmpty(Profile profile) {

View on GitHub (pinned to e4093d4e12)

Solutions

  1. If Maven 3 consumers must read your artifact: remove the features that require the newer model version (check what bumped the computed model version)
  2. If Maven 3 compatibility is not required: add the attribute preserve.model.version='true' on the <project> element to acknowledge and silence the warning
  3. Verify afterwards by opening the installed target's consumer POM and, if needed, consuming it from a Maven 3 build

Example fix

<!-- before -->
<project xmlns="http://maven.apache.org/POM/4.1.0">
  <modelVersion>4.1.0</modelVersion>
  ...
</project>
<!-- after (accept non-consumable consumer POM) -->
<project xmlns="http://maven.apache.org/POM/4.1.0" preserve.model.version="true">
  <modelVersion>4.1.0</modelVersion>
  ...
</project>
Defensive patterns

Strategy: validation

Validate before calling

# CI guard: fail when a to-be-published POM needs a newer model than consumers support
MODEL=$(mvn -q help:evaluate -Dexpression=project.modelVersion -DforceStdout)
if [ "$MODEL" != "4.0.0" ] && ! grep -q 'preserve.model.version="true"' pom.xml; then
  echo "consumer POM will not be Maven 3 consumable"; exit 1
fi

Prevention

When it happens

Trigger: A modelVersion 4.1+ project consumes newer model features (new scopes, consumer-POM-only constructs, etc.) so MavenModelVersion.getModelVersion returns something above 4.0.0, and preserve.model.version was not set to keep it deliberately.

Common situations: Maven 4 projects whose artifacts must also build as dependencies from Maven 3 builds (mixed toolchains in one organization); libraries published for wide consumption.

Related errors


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