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
- Use the Provider<RegularFile> overload: `node.plugin(project.getLayout().getBuildDirectory().file('plugins/myplugin.zip'))`.
- Install from a task output provider, e.g. `node.plugin(tasks.named('zipPlugin', Zip).map(t -> t.getArchiveFile().get())`.
- 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
- Never call node.plugin(String); always pass a Provider<RegularFile>.
- Wrap a TaskProvider's archive via .map(t -> t.getArchiveFile()).
- Add a convention lint that flags String-based plugin/module calls.
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
- Can't treat {} as single node as it has {} nodes
- Number of nodes should be >= 1 but was {} for {}
- Cannot shrink {} to have {} nodes as it already has {}
- Cannot add nodes to test cluster after is has been frozen
- Configuration for {} can not be altered, already locked
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/3ec5e5a88661c8cf.
Report an issue: GitHub.