elastic/elasticsearch · error · RuntimeException
Cannot have null or empty IDs in [elasticsearch-plugins.yml]
Error message
Cannot have null or empty IDs in [elasticsearch-plugins.yml]
What it means
Thrown by PluginsConfig.validate when any InstallablePlugin in elasticsearch-plugins.yml is null or has a null/blank id. Note this is a generic RuntimeException (not a PluginSyncException like the sibling checks), so it propagates with no dedicated exit code. It is the first validation gate before duplicate- and location-checking.
Source
Thrown at distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/PluginsConfig.java:68
this.proxy = proxy;
}
/**
* Validate this instance. For example:
* <ul>
* <li>All {@link InstallablePlugin}s must have IDs</li>
* <li>Any proxy must be well-formed.</li>
* <li>Unofficial plugins must have locations</li>
* </ul>
*
* @param officialPlugins the plugins that can be installed by name only
* @param migratedPlugins plugins that were once official but have since become modules. These
* plugin IDs can still be specified, but do nothing.
* @throws PluginSyncException if validation problems are found
*/
public void validate(Set<String> officialPlugins, Set<String> migratedPlugins) throws PluginSyncException {
if (this.plugins.stream().anyMatch(each -> each == null || Strings.isNullOrBlank(each.getId()))) {
throw new RuntimeException("Cannot have null or empty IDs in [elasticsearch-plugins.yml]");
}
final Set<String> uniquePluginIds = new HashSet<>();
for (final InstallablePlugin plugin : plugins) {
if (uniquePluginIds.add(plugin.getId()) == false) {
throw new PluginSyncException("Duplicate plugin ID [" + plugin.getId() + "] found in [elasticsearch-plugins.yml]");
}
}
for (InstallablePlugin plugin : this.plugins) {
if (officialPlugins.contains(plugin.getId()) == false
&& migratedPlugins.contains(plugin.getId()) == false
&& plugin.getLocation() == null) {
throw new PluginSyncException(
"Must specify location for non-official plugin [" + plugin.getId() + "] in [elasticsearch-plugins.yml]"
);
}
}View on GitHub (pinned to db6a809a66)
Solutions
- Open elasticsearch-plugins.yml and ensure every entry under `plugins:` has a non-empty `id:` value.
- Validate the YAML before deploying: `yq '.plugins[].id' elasticsearch-plugins.yml` should print one id per entry with no blanks.
- If a list slot is intentionally empty, remove the empty `-` item entirely.
Example fix
# before:
plugins:
- id: analysis-icu
- location: file:///opt/x # missing id -> error
# after:
plugins:
- id: analysis-icu
- id: custom-x
location: file:///opt/x Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate the yml before invoking PluginsConfig.validate.
for (InstallablePlugin p : parsed.getPlugins()) {
if (p == null || Strings.isNullOrBlank(p.getId())) {
throw new IllegalArgumentException("Every plugin needs a non-blank id");
}
} Prevention
- Lint elasticsearch-plugins.yml in CI: every `- id:` must have a value.
- Use a schema validator (e.g. JSON Schema for the YAML) before deploy.
- Generate the file from a templating system that always sets id.
When it happens
Trigger: Parsing elasticsearch-plugins.yml yields a plugins list where at least one entry is null or its `id` field is missing/whitespace. The stream `anyMatch(each -> each == null || Strings.isNullOrBlank(each.getId()))` returns true and the exception fires.
Common situations: Hand-edited elasticsearch-plugins.yml with a list item missing the `id:` key; YAML parser produced a null entry from `- ` with no body; copy-paste of a plugin block that dropped the id line.
Related errors
- Duplicate plugin ID [{id}] found in [elasticsearch-plugins.y
- Must specify location for non-official plugin [{id}] in [ela
- Malformed [proxy], expected [host:port] in [elasticsearch-pl
- Empty location for plugin [{id}]
- Malformed location for plugin [{id}]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/0520bf2b57af7757.
Report an issue: GitHub.