{"record":{"id":"ac59928e60a05a91","repo":"elastic/elasticsearch","slug":"78-ac5992","errorCode":"78","errorMessage":"plugin [%s] not found; run 'elasticsearch-plugin list' to get list of installed plugins","messagePattern":"plugin \\[(.+?)\\] not found; run 'elasticsearch-plugin list' to get list of installed plugins","errorType":"exception","errorClass":"UserException","httpStatus":null,"severity":"error","filePath":"distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/RemovePluginAction.java","lineNumber":146,"sourceCode":"        /*\n         * 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\n         * 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\n         * not exist, the plugin config does, and we are not purging, again fail to the user that the plugin is not found.\n         */\n        if ((Files.exists(pluginDir) == false && Files.exists(pluginConfigDir) == false && Files.exists(removing) == false)\n            || (Files.exists(pluginDir) == false && Files.exists(pluginConfigDir) && this.purge == false)) {\n\n            if (PLUGINS_CONVERTED_TO_MODULES.contains(pluginId)) {\n                terminal.errorPrintln(\n                    \"plugin [\" + pluginId + \"] is no longer a plugin but instead a module packaged with this distribution of Elasticsearch\"\n                );\n            } else {\n                final String message = String.format(\n                    Locale.ROOT,\n                    \"plugin [%s] not found; run 'elasticsearch-plugin list' to get list of installed plugins\",\n                    pluginId\n                );\n                throw new UserException(ExitCodes.CONFIG, message);\n            }\n        }\n\n        final Path pluginBinDir = env.binDir().resolve(pluginId);\n        if (Files.exists(pluginBinDir)) {\n            if (Files.isDirectory(pluginBinDir) == false) {\n                throw new UserException(ExitCodes.IO_ERROR, \"bin dir for \" + pluginId + \" is not a directory\");\n            }\n        }\n    }\n\n    private void removePlugin(InstallablePlugin plugin) throws IOException {\n        final String pluginId = plugin.getId();\n        final Path pluginDir = env.pluginsDir().resolve(pluginId);\n        final Path pluginConfigDir = env.configDir().resolve(pluginId);\n        final Path removing = env.pluginsDir().resolve(\".removing-\" + pluginId);\n\n        terminal.println(\"-> removing [\" + pluginId + \"]...\");","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/RemovePluginAction.java#L128-L164","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Run `elasticsearch-plugin list` and copy the exact installed id.","If the id is now a module, no removal is needed (the CLI prints a notice).","If you manually deleted the plugin dir, also remove any stale `.removing-<id>` marker or use `--purge`."],"exampleFix":"# before:\nbin/elasticsearch-plugin remove analisys-icu   # typo\n# after:\nbin/elasticsearch-plugin list   # confirm exact id\nbin/elasticsearch-plugin remove analysis-icu","handlingStrategy":"validation","validationCode":"// Confirm the plugin is installed before removing.\nPath pluginDir = env.pluginsDir().resolve(id);\nif (!Files.exists(pluginDir) && !Files.exists(env.configDir().resolve(id))) {\n    throw new FileNotFoundException(\"plugin not installed: \" + id);\n}","typeGuard":null,"tryCatchPattern":"try {\n    removeAction.execute(plugins);\n} catch (UserException e) {\n    if (e.exitCode == ExitCodes.CONFIG && e.getMessage().contains(\"not found\")) {\n        System.err.println(\"Run `elasticsearch-plugin list` to see installed plugins.\");\n    }\n    throw e;\n}","preventionTips":["Always source removal ids from `elasticsearch-plugin list` output.","In automation, diff installed vs requested before invoking remove.","Handle migrated-to-module ids specially (no removal needed)."],"tags":["plugin-remove","validation","plugin-cli","configuration"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}