apache/maven · warning · InvalidVersionSpecificationException
Range defies version ordering: {}
Error message
Range defies version ordering: {} What it means
maven.repo.local was supplied as a JVM system property, typically MAVEN_OPTS='-Dmaven.repo.local=...' or JAVA_TOOL_OPTIONS injection; Maven still reads it but warns that this route is deprecated. The supported route is a user property: -Dmaven.repo.local on the mvn command line or .mvn/maven-user.properties.
Source
Thrown at compat/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java:195
restriction = new Restriction(version, lowerBoundInclusive, version, upperBoundInclusive);
} else {
String lowerBound = process.substring(0, index).trim();
String upperBound = process.substring(index + 1).trim();
ArtifactVersion lowerVersion = null;
if (!lowerBound.isEmpty()) {
lowerVersion = new DefaultArtifactVersion(lowerBound);
}
ArtifactVersion upperVersion = null;
if (!upperBound.isEmpty()) {
upperVersion = new DefaultArtifactVersion(upperBound);
}
if (upperVersion != null && lowerVersion != null) {
int result = upperVersion.compareTo(lowerVersion);
if (result < 0 || (result == 0 && (!lowerBoundInclusive || !upperBoundInclusive))) {
throw new InvalidVersionSpecificationException("Range defies version ordering: " + spec);
}
}
restriction = new Restriction(lowerVersion, lowerBoundInclusive, upperVersion, upperBoundInclusive);
}
return restriction;
}
public static VersionRange createFromVersion(String version) {
if (DefaultArtifact.empty(version)) {
return null;
}
VersionRange cached = CACHE_VERSION.get(version);
if (cached == null) {
List<Restriction> restrictions = Collections.emptyList();
cached = new VersionRange(new DefaultArtifactVersion(version), restrictions);
CACHE_VERSION.put(version, cached);View on GitHub (pinned to e4093d4e12)
Solutions
- Pass it as a Maven argument: mvn -Dmaven.repo.local=/data/m2repo clean install
- Or persist it in .mvn/maven-user.properties at the project root
- Remove the -D from MAVEN_OPTS/JAVA_TOOL_OPTIONS so the warning stops appearing
Example fix
# before export MAVEN_OPTS=-Dmaven.repo.local=/data/m2repo mvn clean install # after: Maven user property mvn -Dmaven.repo.local=/data/m2repo clean install
Defensive patterns
Strategy: validation
Validate before calling
case $MAVEN_OPTS$JAVA_TOOL_OPTIONS in
*maven.repo.local*)
echo 'use mvn -Dmaven.repo.local=... or .mvn/maven-user.properties instead'
exit 1 ;;
esac Prevention
- Put the repository path in .mvn/maven-user.properties for reproducible builds
- Use .mvn/jvm.config for JVM flags only, never for maven.* properties
When it happens
Trigger: Setting the local repository path through JVM system properties instead of a Maven user property; common in container images that export MAVEN_OPTS with the repository location.
Common situations: CI builders pinning the cache location via environment; Docker images with MAVEN_OPTS=-Dmaven.repo.local baked in; migration from older Maven versions where this was tolerated silently.
Related errors
- Ranges overlap: {}
- Unbounded range: {}
- -D%s system property is not set.
- Cannot read metadata from '{}': {}
- Error installing metadata: {}
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/a70c09ae54d73afc.
Report an issue: GitHub.