apache/maven · error · VersionParserException

Unable to parse version constraint:

Error message

Unable to parse version constraint: 

What it means

DefaultModelVersionParser.DefaultVersionConstraint parses composite constraints — a version range optionally followed by a preferred version (e.g. '[1.0,2.0)1.5', '1.5') — via the resolver VersionScheme. Strings the scheme cannot interpret as a constraint throw VersionParserException('Unable to parse version constraint: <input>'). Unlike parseVersionRange, a bare version IS valid here (it becomes a recommended version), but malformed ranges, bad separators, or garbage suffixes are rejected.

Source

Thrown at impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultModelVersionParser.java:225

            return delegate.equals(that.delegate);
        }

        @Override
        public int hashCode() {
            return delegate.hashCode();
        }
    }

    static class DefaultVersionConstraint implements VersionConstraint {
        private final VersionScheme versionScheme;
        private final org.eclipse.aether.version.VersionConstraint delegate;

        DefaultVersionConstraint(VersionScheme versionScheme, String delegateValue) {
            this.versionScheme = versionScheme;
            try {
                this.delegate = versionScheme.parseVersionConstraint(delegateValue);
            } catch (InvalidVersionSpecificationException e) {
                throw new VersionParserException("Unable to parse version constraint: " + delegateValue, e);
            }
        }

        @Override
        public boolean contains(Version version) {
            if (version instanceof DefaultVersion defaultVersion) {
                return delegate.containsVersion(defaultVersion.delegate);
            } else {
                return contains(new DefaultVersion(versionScheme, version.toString()));
            }
        }

        @Override
        public VersionRange getVersionRange() {
            if (delegate.getRange() == null) {
                return null;
            }
            return new DefaultVersionRange(versionScheme, delegate.getRange());

View on GitHub (pinned to e4093d4e12)

Solutions

  1. Build constraints in canonical form: a valid range optionally immediately followed by a valid plain version, or a single plain version
  2. Validate the two components separately first (parseVersionRange + parseVersion) to pinpoint which half is malformed
  3. Reject blank and '${...}' inputs before parsing

Example fix

// before
VersionConstraint c = parser.parseVersionConstraint(range + ' ' + version); // space breaks parsing

// after
VersionConstraint c = parser.parseVersionConstraint(range + version); // e.g. '[1.0,2.0)' + '1.5'
Defensive patterns

Strategy: try-catch

Validate before calling

// validate components first to pinpoint the bad half
if (rangePart != null) parser.parseVersionRange(rangePart);
if (versionPart != null) parser.parseVersion(versionPart);

Try / catch

try {
    VersionConstraint c = parser.parseVersionConstraint(spec);
} catch (VersionParserException e) {
    throw new IllegalArgumentException('Bad version constraint "' + spec + '"', e);
}

Prevention

When it happens

Trigger: session.getService(VersionParser.class).parseVersionConstraint('[1.0') (unbalanced bracket), parseVersionConstraint('[1.0,2.0)abc') (invalid preferred version), or an uninterpolated/blank property value.

Common situations: Generated constraint strings concatenating range and version without correct order; blank properties defaulting to empty string; migrating code that built constraint strings by hand instead of using range+version fields; typos in the trailing recommended version.

Understand the failure class

Related errors


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