elastic/elasticsearch · error · IllegalArgumentException
Invalid version format: '{s}'. Should be {pattern}
Error message
Invalid version format: '{s}'. Should be {pattern} What it means
Thrown by QualifiedVersion.of when the supplied string does not match the strict semver pattern held in `pattern`. The matcher requires a precise major.minor.patch(+qualifier) shape; any deviation — missing component, extra segments, non-numeric parts — fails matcher.matches() and the task rejects the input with the expected pattern echoed in the message.
Source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/release/QualifiedVersion.java:43
*/
public record QualifiedVersion(int major, int minor, int revision, Qualifier qualifier) implements Comparable<QualifiedVersion> {
private static final Pattern pattern = Pattern.compile(
"^v? (\\d+) \\. (\\d+) \\. (\\d+) (?: - (alpha\\d+ | beta\\d+ | rc\\d+ | SNAPSHOT ) )? $",
Pattern.COMMENTS
);
/**
* Parses the supplied string into an object.
*
* @param s a version string in strict semver
* @return a new instance
*/
public static QualifiedVersion of(final String s) {
Objects.requireNonNull(s);
Matcher matcher = pattern.matcher(s);
if (matcher.matches() == false) {
throw new IllegalArgumentException("Invalid version format: '" + s + "'. Should be " + pattern);
}
return new QualifiedVersion(
Integer.parseInt(matcher.group(1)),
Integer.parseInt(matcher.group(2)),
Integer.parseInt(matcher.group(3)),
matcher.group(4) == null ? null : Qualifier.of(matcher.group(4))
);
}
@Override
public String toString() {
return String.format(Locale.ROOT, "%d.%d.%d%s", major, minor, revision, qualifier == null ? "" : "-" + qualifier);
}
public boolean hasQualifier() {
return qualifier != null;
}View on GitHub (pinned to db6a809a66)
Solutions
- Reformat the version string to strict major.minor.patch with an optional qualifier that Qualifier.of accepts (e.g. '8.0.0', '8.0.0-alpha1', '8.0.0-rc1').
- Check the echoed `pattern` in the message for the exact accepted shape and align the input.
- If the input legitimately carries build metadata, parse/strip it before calling QualifiedVersion.of.
- Add a unit test for the version string to catch regressions in the producing tool.
Example fix
// before
QualifiedVersion.of("8.0");
QualifiedVersion.of("8.0.0.1");
// after
QualifiedVersion.of("8.0.0");
QualifiedVersion.of("8.0.1"); Defensive patterns
Strategy: validation
Validate before calling
private static final Pattern STRICT_SEMVER =
Pattern.compile("^(\\d+)\\.(\\d+)\\.(\\d+)(?:-(\\p{Alnum}+))?$");
if (STRICT_SEMVER.matcher(s).matches() == false) {
throw new IllegalArgumentException("Not strict semver: " + s);
} Type guard
static boolean isQualifiedVersion(String s) {
return s != null && STRICT_SEMVER.matcher(s).matches();
} Try / catch
try { QualifiedVersion v = QualifiedVersion.of(s); }
catch (IllegalArgumentException e) {
// normalize s (strip build metadata) then retry, or surface to the user
throw e;
} Prevention
- Normalize version strings to strict semver before calling QualifiedVersion.of.
- Validate versions from external sources (git tags, env vars) at the boundary.
- Keep release tooling consistent — don't mix Maven and strict semver shapes.
When it happens
Trigger: QualifiedVersion.of(s) is called with a string that isn't strict semver: missing patch (e.g. '8.0'), extra build metadata formatted wrong, a non-numeric component, leading zeros, or a qualifier that doesn't match Qualifier.of's accepted set. The pattern is matched before any parsing, so the failure is purely format validation.
Common situations: Passing a Maven-style version ('8.0.0-SNAPSHOT' may be valid, but '8.0' or '8.0.0.1' is not); a version string sourced from a git tag/env var that includes extra metadata; copy-paste error; mixing qualified and unqualified semver formats across release tooling.
Related errors
- Invalid tag format [{l}]
- Output file not specified
- No version ids found in {javaVersionsFile}
- malformed version [${version}] for jdk [${name}]
- Malformed jdk version [${version}]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/b07dab75ee231cf6.
Report an issue: GitHub.