{"record":{"id":"1e3251d089646512","repo":"elastic/elasticsearch","slug":"plugins-config-does-not-exist-configpath","errorCode":null,"errorMessage":"Plugins config does not exist: {configPath}","messagePattern":"Plugins config does not exist: (.+?)","errorType":"exception","errorClass":"PluginSyncException","httpStatus":null,"severity":"error","filePath":"distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/SyncPluginsAction.java","lineNumber":87,"sourceCode":"                    + 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\n        if (Files.exists(configPath) == false) {\n            // The `PluginsManager` will have checked that this file exists before invoking the action.\n            throw new PluginSyncException(\"Plugins config does not exist: \" + configPath.toAbsolutePath());\n        }\n\n        if (Files.exists(env.pluginsDir()) == false) {\n            throw new PluginSyncException(\"Plugins directory missing: \" + env.pluginsDir());\n        }\n\n        // Parse descriptor file\n        final PluginsConfig pluginsConfig = PluginsConfig.parseConfig(configPath, YamlXContent.yamlXContent);\n        pluginsConfig.validate(InstallPluginAction.OFFICIAL_PLUGINS, InstallPluginAction.PLUGINS_CONVERTED_TO_MODULES);\n\n        // Parse cached descriptor file, if it exists\n        final Optional<PluginsConfig> cachedPluginsConfig = Files.exists(previousConfigPath)\n            ? Optional.of(PluginsConfig.parseConfig(previousConfigPath, CborXContent.cborXContent))\n            : Optional.empty();\n\n        final PluginChanges changes = getPluginChanges(pluginsConfig, cachedPluginsConfig);\n\n        if (changes.isEmpty()) {","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/SyncPluginsAction.java#L69-L105","documentation":"Thrown by SyncPluginsAction.execute when env.configDir()/elasticsearch-plugins.yml does not exist. Sync is only ever invoked when the manager believes the file should be there, so its absence is treated as an inconsistent state and surfaces as PluginSyncException (no dedicated exit code — it propagates through the sync flow).","triggerScenarios":"execute resolves configPath and previousConfigPath; `Files.exists(configPath) == false` throws PluginSyncException with the absolute path. Normally the PluginsManager checks existence before invoking the action, so hitting this indicates that guard was bypassed or the file was deleted between the check and the call.","commonSituations":"Race where the yml is removed after the manager's existence check; a custom caller invoking SyncPluginsAction directly without pre-checking; filesystem issue making the file invisible (permissions, broken mount); misconfigured config dir.","solutions":["Restore elasticsearch-plugins.yml in the configured config dir and rerun the sync / restart the node.","Verify config dir correctness (`path.conf` / ES_PATH_CONF) and that the process can read the file.","If you did not intend to use sync, ensure the action is not invoked (check PluginsManager trigger conditions)."],"exampleFix":"# before: config dir lacks elasticsearch-plugins.yml but sync was triggered\nls <config>/elasticsearch-plugins.yml   # missing\n# after: restore the file (or remove the sync trigger)\ncp /backup/elasticsearch-plugins.yml <config>/\nsystemctl restart elasticsearch","handlingStrategy":"validation","validationCode":"// Ensure the yml exists before invoking sync.\nPath yml = env.configDir().resolve(\"elasticsearch-plugins.yml\");\nif (!Files.exists(yml)) {\n    throw new FileNotFoundException(\"elasticsearch-plugins.yml missing at \" + yml);\n}","typeGuard":null,"tryCatchPattern":"try {\n    syncAction.execute();\n} catch (PluginSyncException e) {\n    if (e.getMessage().contains(\"does not exist\")) {\n        // restore the config file or disable the sync trigger\n        System.err.println(\"Config missing; restore elasticsearch-plugins.yml or disable sync.\");\n    }\n    throw e;\n}","preventionTips":["Treat the existence check and the sync call as one atomic operation.","Do not delete elasticsearch-plugins.yml while the node is running.","Validate config dir permissions and mounts before relying on sync."],"tags":["plugin-sync","configuration","plugin-cli"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}