elastic/elasticsearch · error · UserException

1

1

Error message

plugin directory [%s] already exists; if you need to update the plugin, uninstall it first using command 'remove %s'

What it means

Thrown by verifyPluginName (after the module check) when pluginPath.resolve(pluginName) already exists on disk. The install path is occupied, so a fresh install is refused with PLUGIN_EXISTS (1). The message instructs the user to remove the existing plugin first.

Source

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

    }

    // checking for existing version of the plugin
    private static void verifyPluginName(Path pluginPath, String pluginName) throws UserException, IOException {
        // don't let user install plugin conflicting with module...
        // they might be unavoidably in maven central and are packaged up the same way)
        if (MODULES.contains(pluginName)) {
            throw new UserException(ExitCodes.USAGE, "plugin '" + pluginName + "' cannot be installed as a plugin, it is a system module");
        }

        final Path destination = pluginPath.resolve(pluginName);
        if (Files.exists(destination)) {
            final String message = String.format(
                Locale.ROOT,
                "plugin directory [%s] already exists; if you need to update the plugin, " + "uninstall it first using command 'remove %s'",
                destination,
                pluginName
            );
            throw new UserException(PLUGIN_EXISTS, message);
        }
    }

    /**
     * Load information about the plugin, and verify it can be installed with no errors.
     */
    private PluginDescriptor loadPluginInfo(Path pluginRoot) throws Exception {
        final PluginDescriptor info = PluginDescriptor.readFromProperties(pluginRoot);
        if (info.hasNativeController()) {
            throw new IllegalStateException("plugins can not have native controllers");
        }
        PluginsUtils.verifyCompatibility(info);

        // checking for existing version of the plugin
        verifyPluginName(env.pluginsDir(), info.getName());

        PluginsUtils.checkForFailedPluginRemovals(env.pluginsDir());

View on GitHub (pinned to db6a809a66)

Solutions

  1. Run `elasticsearch-plugin remove <name>` first, then install.
  2. If the directory is leftover from a failed install, delete it manually: `rm -rf $ES_HOME/plugins/<name>`.
  3. Make deployment scripts idempotent by checking for the directory (or always remove-then-install).

Example fix

# before
elasticsearch-plugin install analysis-icu   # dir exists
# after
elasticsearch-plugin remove analysis-icu && elasticsearch-plugin install analysis-icu
Defensive patterns

Strategy: validation

Validate before calling

Path dest = env.pluginsDir().resolve(pluginName);
if (Files.exists(dest)) {
    // either skip (already installed) or remove first
    throw new IllegalStateException("Plugin dir exists, run remove first: " + dest);
}

Prevention

When it happens

Trigger: Running `install X` when `$ES_HOME/plugins/X` already exists; an earlier failed install left a partial directory; reinstalling without removing.

Common situations: Retry-after-failure leaving stub directories; idempotent deployment scripts that re-run install on already-provisioned hosts; manual upgrades done by re-installing.

Related errors


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