elastic/elasticsearch · error · GradleException

Malformed lucene snapshot version: ${luceneVersion}

Error message

Malformed lucene snapshot version: ${luceneVersion}

What it means

Thrown by RepositoriesSetupPlugin.configureRepositories when the Lucene version (from VersionProperties.getLucene()) contains '-snapshot' but does not match LUCENE_SNAPSHOT_REGEX '\\w+-snapshot-([a-z0-9]+)'. The regex extracts the alphanumeric revision so the plugin can build the S3 snapshot repository URL and the exclusive-content version filter; a snapshot version without a parseable revision suffix cannot be wired to a repository.

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/RepositoriesSetupPlugin.java:50

    /**
     * Adds repositories used by ES projects and dependencies
     */
    public static void configureRepositories(Project project) {
        RepositoryHandler repos = project.getRepositories();
        if (System.getProperty("repos.mavenLocal") != null) {
            // with -Drepos.mavenLocal=true we can force checking the local .m2 repo which is
            // useful for development ie. bwc tests where we install stuff in the local repository
            // such that we don't have to pass hardcoded files to gradle
            repos.mavenLocal();
        }
        repos.mavenCentral();

        String luceneVersion = VersionProperties.getLucene();
        if (luceneVersion.contains("-snapshot")) {
            // extract the revision number from the version with a regex matcher
            Matcher matcher = LUCENE_SNAPSHOT_REGEX.matcher(luceneVersion);
            if (matcher.find() == false) {
                throw new GradleException("Malformed lucene snapshot version: " + luceneVersion);
            }
            String revision = matcher.group(1);
            MavenArtifactRepository luceneRepo = repos.maven(repo -> {
                repo.setName("lucene-snapshots");
                repo.setUrl("https://s3.amazonaws.com/download.elasticsearch.org/lucenesnapshots/" + revision);
            });
            repos.exclusiveContent(exclusiveRepo -> {
                exclusiveRepo.filter(
                    descriptor -> descriptor.includeVersionByRegex("org\\.apache\\.lucene", ".*", ".*-snapshot-" + revision)
                );
                exclusiveRepo.forRepositories(luceneRepo);
            });
        }

        String cuvsVersion = VersionProperties.getVersions().get("cuvs_java");
        if (cuvsVersion.contains("-SNAPSHOT")) {
            MavenArtifactRepository cuvsRepo = repos.maven(repo -> {
                repo.setName("cuvs-snapshots");

View on GitHub (pinned to db6a809a66)

Solutions

  1. Set the lucene version in VersionProperties to the canonical snapshot form '<base>-snapshot-<revision>', e.g. '9.12.0-snapshot-9abc123'.
  2. Use only lowercase [a-z0-9] in the revision portion (the regex is case-sensitive).
  3. If you intentionally want a non-snapshot Lucene, remove the '-snapshot' segment entirely so the contains() guard is false and no regex parse is attempted.
  4. Regenerate version properties through the build's versioning tooling rather than hand-editing.

Example fix

// before (version.properties): lucene = 9.12.0-SNAPSHOT
// after:                  lucene = 9.12.0-snapshot-9abc123
Defensive patterns

Strategy: validation

Validate before calling

import java.util.regex.Pattern;
private static final Pattern LUCENE_SNAPSHOT = Pattern.compile("\\w+-snapshot-([a-z0-9]+)");
void checkLuceneVersion(String v) {
    if (v.contains("-snapshot")) {
        if (!LUCENE_SNAPSHOT.matcher(v).find())
            throw new IllegalArgumentException("bad lucene snapshot version: " + v);
    }
}
// canonical: "9.12.0-snapshot-9abc123"

Prevention

When it happens

Trigger: luceneVersion.contains("-snapshot") is true, but LUCENE_SNAPSHOT_REGEX.matcher(luceneVersion).find() is false. The regex expects the form '<something>-snapshot-<revision>' where revision is lowercase letters/digits (e.g. '9.10.0-snapshot-1a2b3c').

Common situations: VersionProperties lucene version malformed (missing the revision tail after '-snapshot'); a version like '9.10.0-SNAPSHOT' (Maven-style uppercase, no revision — does not contain lowercase '-snapshot'); uppercase letters or symbols in the revision that violate [a-z0-9]+; manually editing version.properties with a non-canonical snapshot string.

Understand the failure class

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/0b63287031445c29. Report an issue: GitHub.