elastic/elasticsearch · error · TestClustersException

Task {} can't use test cluster from another project {}

Error message

Task {} can't use test cluster from another project {}

What it means

TestClustersAware.useCluster() rejects registering a cluster whose Gradle project path differs from the task's own project path. Test clusters are build-scoped singletons owned by a project; a task in project `:a` cannot reference a cluster declared in project `:b` because lifecycle, cleanup, and `dependsOn` wiring all assume co-location. The check is by `cluster.getPath()` (the cluster's project) vs `getProject().getPath()`.

Source

Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/TestClustersAware.java:36

import java.util.Collection;

import static org.elasticsearch.gradle.testclusters.TestClustersPlugin.REGISTRY_SERVICE_NAME;
import static org.elasticsearch.gradle.testclusters.TestClustersPlugin.TEST_CLUSTER_TASKS_SERVICE;

public interface TestClustersAware extends Task {

    @Nested
    Collection<ElasticsearchCluster> getClusters();

    @ServiceReference(REGISTRY_SERVICE_NAME)
    Property<TestClustersRegistry> getRegistry();

    @ServiceReference(TEST_CLUSTER_TASKS_SERVICE)
    Property<TestClustersPlugin.TaskEventsService> getTasksService();

    default void useCluster(ElasticsearchCluster cluster) {
        if (cluster.getPath().equals(getProject().getPath()) == false) {
            throw new TestClustersException("Task " + getPath() + " can't use test cluster from" + " another project " + cluster);
        }
        if (cluster.getName().equals(getName())) {
            for (ElasticsearchNode node : cluster.getNodes()) {
                for (ElasticsearchDistribution distro : node.getDistributions()) {
                    ElasticsearchDistribution frozenDistro = distro.maybeFreeze();
                    dependsOn(frozenDistro);
                }
            }
            dependsOn(cluster.getPluginAndModuleConfigurations());
        }
        getClusters().add(cluster);
    }

    default Provider<TestClusterInfo> getClusterInfo(String clusterName) {
        return getProject().getProviders().of(TestClusterValueSource.class, source -> {
            source.getParameters().getService().set(getRegistry());
            source.getParameters().getClusterName().set(clusterName);
            source.getParameters().getPath().set(getProject().getIsolated().getPath());

View on GitHub (pinned to db6a809a66)

Solutions

  1. Declare the `ElasticsearchCluster` in the SAME project as the task that calls `useCluster(...)`.
  2. If you need an identical cluster shape in multiple projects, define it (or apply a convention that defines it) in each project — they are cheap to declare.
  3. Move the task into the project that owns the cluster, or move the cluster declaration into the task's project.
  4. Do NOT attempt to bridge via `rootProject` references — the guard exists precisely to prevent this.

Example fix

// before: in :a/build.gradle
useCluster(rootProject.testClusters.shared)
// after: declare locally
ElasticsearchCluster shared = testClusters.create('shared')
useCluster(shared)
Defensive patterns

Strategy: validation

Validate before calling

if (!cluster.getPath().equals(task.getProject().getPath())) {
  throw new TestClustersException(
    "Cluster must be declared in " + task.getProject().getPath() + "; it is in " + cluster.getPath());
}

Prevention

When it happens

Trigger: Calling `task.useCluster(testClusters.<name>)` where `testClusters` resolves to a cluster container in a different subproject than the task. Common when referencing `rootProject.testClusters.x` or `project(':other').testclusters.x` from a task in the current project.

Common situations: Sharing a cluster across modules to save startup time (not supported); copy-pasting a `useCluster` line from a sibling module; applying a convention plugin that wires clusters defined in the root project into subproject tasks.

Related errors


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