elastic/elasticsearch · error · IllegalStateException

{className} can only be applied to the root project.

Error message

{className} can only be applied to the root project.

What it means

Thrown by GlobalBuildInfoPlugin.apply(Project) when the plugin is applied to a Gradle subproject instead of the root project. GlobalBuildInfoPlugin is the central build-info plugin that registers the Java toolchain, JDK download, version properties, git info, and build parameters extensions. These are singletons that must exist once at the root. The guard is an identity check: project != project.getRootProject().

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/info/GlobalBuildInfoPlugin.java:112

    @Inject
    public GlobalBuildInfoPlugin(
        ObjectFactory objectFactory,
        JavaInstallationRegistry javaInstallationRegistry,
        JvmMetadataDetector metadataDetector,
        ProviderFactory providers,
        BuildFeatures buildFeatures
    ) {
        this.objectFactory = objectFactory;
        this.javaInstallationRegistry = javaInstallationRegistry;
        this.metadataDetector = new ErrorTraceMetadataDetector(metadataDetector);
        this.providers = providers;
        this.buildFeatures = buildFeatures;
    }

    @Override
    public void apply(Project project) {
        if (project != project.getRootProject()) {
            throw new IllegalStateException(this.getClass().getName() + " can only be applied to the root project.");
        }
        this.project = project;
        project.getPlugins().apply(JvmToolchainsPlugin.class);
        project.getPlugins().apply(JdkDownloadPlugin.class);
        project.getPlugins().apply(VersionPropertiesPlugin.class);
        Provider<GitInfo> gitInfo = project.getPlugins().apply(GitInfoPlugin.class).getGitInfo();

        toolChainService = project.getExtensions().getByType(JavaToolchainService.class);
        GradleVersion minimumGradleVersion = GradleVersion.version(getResourceContents("/minimumGradleVersion"));
        if (GradleVersion.current().compareTo(minimumGradleVersion) < 0) {
            throw new GradleException("Gradle " + minimumGradleVersion.getVersion() + "+ is required");
        }

        Properties versionProperties = (Properties) project.getExtensions().getByName(VERSIONS_EXT);
        JavaVersion minimumCompilerVersion = JavaVersion.toVersion(versionProperties.get("minimumCompilerJava"));
        JavaVersion minimumRuntimeVersion = JavaVersion.toVersion(versionProperties.get("minimumRuntimeJava"));
        Version elasticsearchVersionProperty = Version.fromString(versionProperties.getProperty("elasticsearch"));

View on GitHub (pinned to db6a809a66)

Solutions

  1. Apply GlobalBuildInfoPlugin only in the root build.gradle.
  2. If applying through a convention plugin, guard the convention plugin itself to only apply to the root project.
  3. Subprojects should access build info (toolchain, version properties) via the root project's extensions, not by re-applying the plugin.

Example fix

// before (subproject build.gradle)
apply plugin: 'elasticsearch.global-build-info'

// after (root build.gradle only)
apply plugin: 'elasticsearch.global-build-info'
// subprojects consume extensions registered at root
Defensive patterns

Strategy: validation

Validate before calling

// In a convention plugin, validate before applying
if (project == project.getRootProject()) {
    project.getPlugins().apply(GlobalBuildInfoPlugin.class);
}

Prevention

When it happens

Trigger: Applying GlobalBuildInfoPlugin (directly or transitively via another convention plugin) to a non-root project. Since DockerSupportPlugin and other root-level plugins apply GlobalBuildInfoPlugin, transitively applying any of them to a subproject triggers this.

Common situations: A convention plugin in build-conventions or build-tools-internal that bundles GlobalBuildInfoPlugin is applied per-subproject. A developer adds `id('elasticsearch.global-build-info')` to a subproject's build.gradle. A composite build setup causes the plugin to be applied to an included build's subproject.

Related errors


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