elastic/elasticsearch · error · UnsupportedOperationException

Not Supported API

Error message

Not Supported API

What it means

UnsupportedOperationException thrown by ElasticsearchNode.plugin(String pluginProjectPath) — the String-overload of plugin() is intentionally unsupported. The node only accepts plugin installs as Provider<RegularFile> (resolved file providers), because it needs concrete files rather than project-path references resolved later by Gradle.

Source

Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java:311

        if (testDistribution == TestDistribution.INTEG_TEST) {
            distribution.setType(ElasticsearchDistributionTypes.INTEG_TEST_ZIP);
            // we change the underlying distribution when changing the test distribution of the cluster.
            distribution.setPlatform(null);
            distribution.setBundledJdk(null);
        } else {
            distribution.setType(ElasticsearchDistributionTypes.ARCHIVE);
        }
    }

    @Override
    public void plugin(Provider<RegularFile> plugin) {
        checkFrozen();
        this.plugins.add(plugin.map(RegularFile::getAsFile));
    }

    @Override
    public void plugin(String pluginProjectPath) {
        throw new UnsupportedOperationException("Not Supported API");
    }

    public void plugin(TaskProvider<Zip> plugin) {
        throw new UnsupportedOperationException("Not Supported API");
    }

    @Override
    public void module(Provider<RegularFile> module) {
        checkFrozen();
        this.modules.add(module.map(RegularFile::getAsFile));
    }

    /**
     * Adds a module directory directly from a plain file provider.
     * Used by {@link ElasticsearchCluster} when wiring a {@link org.gradle.api.tasks.Sync} task output,
     * where the destination directory is already resolved as a {@link java.io.File} and does not need
     * to go through the {@code Provider<RegularFile>} abstraction.
     */

View on GitHub (pinned to db6a809a66)

Solutions

  1. Use the Provider<RegularFile> overload: `node.plugin(project.getLayout().getBuildDirectory().file('plugins/myplugin.zip'))`.
  2. Install from a task output provider, e.g. `node.plugin(tasks.named('zipPlugin', Zip).map(t -> t.getArchiveFile().get())`.
  3. Reference the supported plugin(Provider<RegularFile>) overload shown immediately above the throwing one.

Example fix

// before
node.plugin(':my-plugins:foo')  // throws UnsupportedOperationException

// after
node.plugin(project.provider(() -> project.file('build/plugins/foo.zip'))
          .map(f -> project.getLayout().getProjectDirectory().file(f.getPath())))
Defensive patterns

Strategy: validation

Validate before calling

// Resolve to a file provider before calling plugin()
Provider<RegularFile> fileProvider = project.getLayout().getBuildDirectory().file("plugins/foo.zip");
node.plugin(fileProvider);

Type guard

static boolean isSupportedPluginArg(Object arg) {
    return arg instanceof Provider<?> p && (p.get() instanceof RegularFile || p.get() instanceof File);
}

Prevention

When it happens

Trigger: Calling testClusters.cluster.plugin('someProjectPath') or node.plugin('someProjectPath') — i.e. the String variant defined by the testclusters DSL interface but overridden to throw here.

Common situations: Copy-pasting plugin-install snippets from older ES versions or other testcluster implementations that accepted project paths; following the interface contract without noticing the override.

Related errors


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