gradle/gradle · error · IllegalArgumentException

'%s' is not a valid Gradle version string (examples: '9.0.0'

Error message

'%s' is not a valid Gradle version string (examples: '9.0.0', '9.1.0-rc-1')

What it means

DefaultGradleVersion.version(String) parses a version against a strict pattern that expects major.minor.micro plus an optional stage suffix (for example '9.0.0', '9.1.0-rc-1', and milestone/snapshot/commit-id forms). Any string that does not match the whole pattern is rejected immediately with IllegalArgumentException. The message echoes the offending string and shows two example formats.

Source

Thrown at platforms/core-runtime/base-services/src/main/java/org/gradle/util/internal/DefaultGradleVersion.java:118

        return CURRENT;
    }

    /**
     * Parses the given string into a GradleVersion.
     *
     * @throws IllegalArgumentException On unrecognized version string.
     */
    public static DefaultGradleVersion version(String version) throws IllegalArgumentException {
        return new DefaultGradleVersion(version, null, null, null);
    }

    private DefaultGradleVersion(String version, @Nullable String buildTime, @Nullable String commitId, @Nullable String scriptTemplateCommitId) {
        this.version = version;
        this.buildTime = buildTime;
        this.scriptTemplateCommitId = scriptTemplateCommitId;
        Matcher matcher = VERSION_PATTERN.matcher(version);
        if (!matcher.matches()) {
            throw new IllegalArgumentException(format("'%s' is not a valid Gradle version string (examples: '9.0.0', '9.1.0-rc-1')", version));
        }

        versionPart = matcher.group(1);
        majorPart = Integer.parseInt(matcher.group(2), 10);

        this.commitId = setOrParseCommitId(commitId, matcher);
        this.stage = parseStage(matcher);
        this.snapshot = parseSnapshot(matcher);
    }

    private @Nullable Long parseSnapshot(Matcher matcher) {
        if ("snapshot".equals(matcher.group(5)) || isCommitVersion(matcher)) {
            return 0L;
        } else if (matcher.group(8) == null) {
            return null;
        } else if ("SNAPSHOT".equals(matcher.group(8))) {
            return 0L;
        } else {

View on GitHub (pinned to 534f27719b)

Solutions

  1. Supply a full major.minor.micro version such as '9.0.0' or '9.1.0-rc-1'
  2. Normalize before parsing: trim whitespace and strip a leading 'v'
  3. Validate with a regex like ^[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ before calling version()
  4. Wrap the call in try/catch IllegalArgumentException and fall back to a default when the input is free-form

Example fix

// before
DefaultGradleVersion v = DefaultGradleVersion.version(raw); // raw = "v9.0.0"

// after
String normalized = raw.trim().replaceFirst("^v", "");
DefaultGradleVersion v = DefaultGradleVersion.version(normalized); // "9.0.0"
Defensive patterns

Strategy: validation

Validate before calling

static boolean isParsableGradleVersion(String s) {
    return s != null && s.trim().matches("[0-9]+\\.[0-9]+\\.[0-9]+(-.*)?");
}

if (!isParsableGradleVersion(raw)) {
    throw new IllegalArgumentException("Bad Gradle version: " + raw);
}

Try / catch

try {
    DefaultGradleVersion.version(candidate);
} catch (IllegalArgumentException e) {
    // reject the input with your own message; do not retry the same string
}

Prevention

When it happens

Trigger: Calling DefaultGradleVersion.version(...) with '9' (missing minor and micro), '9.0', 'v9.0.0', '9.0.0-rc' (stage without a number), '9.0.0.1' (extra component), an empty string, or a string with leading/trailing whitespace.

Common situations: Build logic or plugins that parse 'gradle --version' output, wrapper distribution URLs, or GRADLE_HOME folder names; versions produced by a different convention (leading 'v', two-part versions); scripts that forget to trim tool output before parsing.

Related errors


AI-assisted analysis of gradle/gradle@534f27719b (2026-08-22). Data as JSON: /api/errors/ef4a85ebbac62f25. Report an issue: GitHub.