elastic/elasticsearch · error · PluginSyncException
Plugins directory missing: {pluginsDir}
Error message
Plugins directory missing: {pluginsDir} What it means
Thrown by SyncPluginsAction.execute() when the ES plugins directory (env.pluginsDir()) does not exist on disk. The plugin-sync flow needs this directory to enumerate currently-installed plugins and diff them against elasticsearch-plugins.yml. Its absence means the ES_HOME layout is incomplete or misconfigured.
Source
Thrown at distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/SyncPluginsAction.java:91
}
}
/**
* Synchronises plugins from the config file to the plugins dir.
*
* @throws Exception if anything goes wrong
*/
public void execute() throws Exception {
final Path configPath = this.env.configDir().resolve(ELASTICSEARCH_PLUGINS_YML);
final Path previousConfigPath = this.env.pluginsDir().resolve(ELASTICSEARCH_PLUGINS_YML_CACHE);
if (Files.exists(configPath) == false) {
// The `PluginsManager` will have checked that this file exists before invoking the action.
throw new PluginSyncException("Plugins config does not exist: " + configPath.toAbsolutePath());
}
if (Files.exists(env.pluginsDir()) == false) {
throw new PluginSyncException("Plugins directory missing: " + env.pluginsDir());
}
// Parse descriptor file
final PluginsConfig pluginsConfig = PluginsConfig.parseConfig(configPath, YamlXContent.yamlXContent);
pluginsConfig.validate(InstallPluginAction.OFFICIAL_PLUGINS, InstallPluginAction.PLUGINS_CONVERTED_TO_MODULES);
// Parse cached descriptor file, if it exists
final Optional<PluginsConfig> cachedPluginsConfig = Files.exists(previousConfigPath)
? Optional.of(PluginsConfig.parseConfig(previousConfigPath, CborXContent.cborXContent))
: Optional.empty();
final PluginChanges changes = getPluginChanges(pluginsConfig, cachedPluginsConfig);
if (changes.isEmpty()) {
terminal.println("No plugins to install, remove or upgrade");
return;
}
View on GitHub (pinned to db6a809a66)
Solutions
- Verify ES_HOME is correct: ls $ES_HOME/plugins — the directory should exist alongside lib/, config/, modules/.
- If using a custom/tar distribution, re-extract the official archive so the plugins/ directory is recreated.
- For Docker, use the official elasticsearch image rather than a hand-built one that drops plugins/.
- If the directory was deleted, recreate it empty (mkdir $ES_HOME/plugins) — sync will treat zero installed plugins as a clean slate.
Example fix
# before: ES_HOME=/opt/es-custom (no plugins/ dir) ls /opt/es-custom/plugins # -> No such file # after mkdir -p /opt/es-custom/plugins
Defensive patterns
Strategy: validation
Validate before calling
Path pluginsDir = env.pluginsDir();
if (Files.exists(pluginsDir) == false) {
throw new IllegalStateException("Plugins directory missing: " + pluginsDir
+ " — check ES_HOME and re-extract the distribution.");
} Prevention
- Use the official ES distribution archive/Docker image so plugins/ is always present.
- In custom images, add a runtime entrypoint check: test -d "$ES_HOME/plugins".
- Never delete the plugins/ directory even if empty.
When it happens
Trigger: Calling the sync-plugins command (or booting Docker ES which invokes it) when ES_HOME/plugins is absent — e.g. ES_HOME pointed at a partial/extracted tarball, a custom distribution missing the plugins dir, or the dir was deleted after install.
Common situations: Running ES from a manually assembled ES_HOME; containers built from a stripped image; symlinking ES_HOME to a read-only mount that omits plugins/; CI images that prune the plugins directory to save space.
Related errors
- Failed to list existing plugins
- 78
- Can't create extra config file from {} for {} as it does not
- Can't create extra config file for
- Failed to write marker file
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/65793a07f2f76153.
Report an issue: GitHub.