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

  1. Verify ES_HOME is correct: ls $ES_HOME/plugins — the directory should exist alongside lib/, config/, modules/.
  2. If using a custom/tar distribution, re-extract the official archive so the plugins/ directory is recreated.
  3. For Docker, use the official elasticsearch image rather than a hand-built one that drops plugins/.
  4. 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

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


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