elastic/elasticsearch · error · UserException

78

78

Error message

plugin [%s] not found; run 'elasticsearch-plugin list' to get list of installed plugins

What it means

Thrown by RemovePluginAction.checkCanRemove when neither the plugin directory nor (conditionally) the plugin config dir exists, and no `.removing-<id>` marker is present. Exit code is CONFIG (78). The message guides the user to run `list` to see installed plugins. A special branch prints a different message for plugins that have become modules.

Source

Thrown at distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/RemovePluginAction.java:146

        /*
         * If the plugin does not exist and the plugin config does not exist, fail to the user that the plugin is not found, unless there's
         * a marker file left from a previously failed attempt in which case we proceed to clean up the marker file. Or, if the plugin does
         * not exist, the plugin config does, and we are not purging, again fail to the user that the plugin is not found.
         */
        if ((Files.exists(pluginDir) == false && Files.exists(pluginConfigDir) == false && Files.exists(removing) == false)
            || (Files.exists(pluginDir) == false && Files.exists(pluginConfigDir) && this.purge == false)) {

            if (PLUGINS_CONVERTED_TO_MODULES.contains(pluginId)) {
                terminal.errorPrintln(
                    "plugin [" + pluginId + "] is no longer a plugin but instead a module packaged with this distribution of Elasticsearch"
                );
            } else {
                final String message = String.format(
                    Locale.ROOT,
                    "plugin [%s] not found; run 'elasticsearch-plugin list' to get list of installed plugins",
                    pluginId
                );
                throw new UserException(ExitCodes.CONFIG, message);
            }
        }

        final Path pluginBinDir = env.binDir().resolve(pluginId);
        if (Files.exists(pluginBinDir)) {
            if (Files.isDirectory(pluginBinDir) == false) {
                throw new UserException(ExitCodes.IO_ERROR, "bin dir for " + pluginId + " is not a directory");
            }
        }
    }

    private void removePlugin(InstallablePlugin plugin) throws IOException {
        final String pluginId = plugin.getId();
        final Path pluginDir = env.pluginsDir().resolve(pluginId);
        final Path pluginConfigDir = env.configDir().resolve(pluginId);
        final Path removing = env.pluginsDir().resolve(".removing-" + pluginId);

        terminal.println("-> removing [" + pluginId + "]...");

View on GitHub (pinned to db6a809a66)

Solutions

  1. Run `elasticsearch-plugin list` and copy the exact installed id.
  2. If the id is now a module, no removal is needed (the CLI prints a notice).
  3. If you manually deleted the plugin dir, also remove any stale `.removing-<id>` marker or use `--purge`.

Example fix

# before:
bin/elasticsearch-plugin remove analisys-icu   # typo
# after:
bin/elasticsearch-plugin list   # confirm exact id
bin/elasticsearch-plugin remove analysis-icu
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the plugin is installed before removing.
Path pluginDir = env.pluginsDir().resolve(id);
if (!Files.exists(pluginDir) && !Files.exists(env.configDir().resolve(id))) {
    throw new FileNotFoundException("plugin not installed: " + id);
}

Try / catch

try {
    removeAction.execute(plugins);
} catch (UserException e) {
    if (e.exitCode == ExitCodes.CONFIG && e.getMessage().contains("not found")) {
        System.err.println("Run `elasticsearch-plugin list` to see installed plugins.");
    }
    throw e;
}

Prevention

When it happens

Trigger: checkCanRemove resolves pluginDir and pluginConfigDir; if pluginDir is absent AND (pluginConfigDir absent OR purge==false), it formats the not-found message and throws UserException(CONFIG). The PLUGINS_CONVERTED_TO_MODULES branch bypasses the throw for known migrated ids.

Common situations: Typo in the plugin id on `remove`; plugin already removed manually; plugin never installed on this node; id is a legacy name now shipped as a module.

Related errors


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