{"record":{"id":"a5930e10c64a3c19","repo":"elastic/elasticsearch","slug":"64-a5930e","errorCode":"64","errorMessage":"Plugins config [{pluginsConfig}] exists, which is used by Elasticsearch on startup to ensure the correct plugins are installed. Instead of using this tool, you need to update this config file and restart Elasticsearch.","messagePattern":"Plugins config \\[(.+?)\\] exists, which is used by Elasticsearch on startup to ensure the correct plugins are installed\\. Instead of using this tool, you need to update this config file and restart Elasticsearch\\.","errorType":"exception","errorClass":"UserException","httpStatus":null,"severity":"error","filePath":"distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/SyncPluginsAction.java","lineNumber":66,"sourceCode":"    public static final String ELASTICSEARCH_PLUGINS_YML_CACHE = \".elasticsearch-plugins.yml.cache\";\n\n    private final Terminal terminal;\n    private final Environment env;\n\n    public SyncPluginsAction(Terminal terminal, Environment env) {\n        this.terminal = terminal;\n        this.env = env;\n    }\n\n    /**\n     * Ensures that the plugin config file does <b>not</b> exist.\n     * @param env the environment to check\n     * @throws UserException if a plugins config file is found.\n     */\n    public static void ensureNoConfigFile(Environment env) throws UserException {\n        final Path pluginsConfig = env.configDir().resolve(ELASTICSEARCH_PLUGINS_YML);\n        if (Files.exists(pluginsConfig)) {\n            throw new UserException(\n                ExitCodes.USAGE,\n                \"Plugins config [\"\n                    + pluginsConfig\n                    + \"] exists, which is used by Elasticsearch on startup to ensure the correct plugins \"\n                    + \"are installed. Instead of using this tool, you need to update this config file and restart Elasticsearch.\"\n            );\n        }\n    }\n\n    /**\n     * Synchronises plugins from the config file to the plugins dir.\n     *\n     * @throws Exception if anything goes wrong\n     */\n    public void execute() throws Exception {\n        final Path configPath = this.env.configDir().resolve(ELASTICSEARCH_PLUGINS_YML);\n        final Path previousConfigPath = this.env.pluginsDir().resolve(ELASTICSEARCH_PLUGINS_YML_CACHE);\n","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/SyncPluginsAction.java#L48-L84","documentation":"Thrown by SyncPluginsAction.ensureNoConfigFile when elasticsearch-plugins.yml exists in env.configDir(). Its presence means plugin management is delegated to the sync flow on startup, so the manual install/remove tooling refuses to run. Exit code USAGE (64). The message tells the user to edit the config and restart instead.","triggerScenarios":"The install/remove CLI calls ensureNoConfigFile(env) before doing work; if `env.configDir().resolve(ELASTICSEARCH_PLUGINS_YML)` exists, UserException(USAGE) is thrown immediately. This prevents the manual and sync flows from racing on plugin state.","commonSituations":"Operator set up declarative plugin management (elasticsearch-plugins.yml) and then tried to run `elasticsearch-plugin install/remove` manually; leftover config file from a previous managed setup.","solutions":["Edit elasticsearch-plugins.yml to add/remove the plugin entry, then restart Elasticsearch so SyncPluginsAction reconciles.","If you want to use the manual CLI, remove or rename elasticsearch-plugins.yml first.","Pick one plugin-management mode (declarative via yml OR manual CLI) and stay consistent."],"exampleFix":"# before: elasticsearch-plugins.yml present, manual CLI blocked\nbin/elasticsearch-plugin install x   # throws\n# after (declarative mode):\n# edit <config>/elasticsearch-plugins.yml to add `x`, then:\nsystemctl restart elasticsearch\n# or (manual mode): remove the yml first\nmv <config>/elasticsearch-plugins.yml{,.bak}\nbin/elasticsearch-plugin install x","handlingStrategy":"validation","validationCode":"// Detect declarative mode before invoking manual install/remove.\nPath yml = env.configDir().resolve(\"elasticsearch-plugins.yml\");\nif (Files.exists(yml)) {\n    throw new IllegalStateException(\"Declarative plugins config present at \" + yml + \" — edit it and restart instead\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    installAction.execute(...);\n} catch (UserException e) {\n    if (e.exitCode == ExitCodes.USAGE && e.getMessage().contains(\"Plugins config\")) {\n        System.err.println(\"This node uses elasticsearch-plugins.yml. Edit it and restart.\");\n    }\n    throw e;\n}","preventionTips":["Choose one plugin management mode (declarative yml OR manual CLI) per cluster.","In runbooks, branch on the presence of elasticsearch-plugins.yml before documenting CLI steps.","CI-test both modes separately so operators do not mix them."],"tags":["plugin-sync","configuration","usage","plugin-cli"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}