{"record":{"id":"ce7c97ecb7e0bc14","repo":"elastic/elasticsearch","slug":"plugins-can-not-have-native-controllers","errorCode":null,"errorMessage":"plugins can not have native controllers","messagePattern":"plugins can not have native controllers","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/InstallPluginAction.java","lineNumber":840,"sourceCode":"        final Path destination = pluginPath.resolve(pluginName);\n        if (Files.exists(destination)) {\n            final String message = String.format(\n                Locale.ROOT,\n                \"plugin directory [%s] already exists; if you need to update the plugin, \" + \"uninstall it first using command 'remove %s'\",\n                destination,\n                pluginName\n            );\n            throw new UserException(PLUGIN_EXISTS, message);\n        }\n    }\n\n    /**\n     * Load information about the plugin, and verify it can be installed with no errors.\n     */\n    private PluginDescriptor loadPluginInfo(Path pluginRoot) throws Exception {\n        final PluginDescriptor info = PluginDescriptor.readFromProperties(pluginRoot);\n        if (info.hasNativeController()) {\n            throw new IllegalStateException(\"plugins can not have native controllers\");\n        }\n        PluginsUtils.verifyCompatibility(info);\n\n        // checking for existing version of the plugin\n        verifyPluginName(env.pluginsDir(), info.getName());\n\n        PluginsUtils.checkForFailedPluginRemovals(env.pluginsDir());\n\n        terminal.println(VERBOSE, info.toString());\n\n        // check for jar hell before any copying\n        jarHellCheck(info, pluginRoot, env.pluginsDir(), env.modulesDir());\n\n        if (info.isStable() && hasNamedComponentFile(pluginRoot) == false) {\n            generateNameComponentFile(pluginRoot);\n        }\n        return info;\n    }","sourceCodeStart":822,"sourceCodeEnd":858,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/InstallPluginAction.java#L822-L858","documentation":"Thrown as a plain IllegalStateException (not a UserException, so no POSIX exit-code mapping — surfaces as an internal error / stack trace) inside loadPluginInfo when PluginDescriptor.readFromProperties reports the plugin declares a native controller. Modern Elasticsearch forbids user-installed plugins from having native controllers; only bundled system components may. This is an invariant violation by the plugin author, not a usage mistake by the operator.","triggerScenarios":"A plugin descriptor file (plugin-descriptor.properties) that sets `java.controller=true` (or equivalent) and is presented for installation via the CLI.","commonSituations":"Third-party plugins copying properties from internal/system components; forks reusing a system plugin template that includes the controller flag.","solutions":["Contact the plugin author to remove the native-controller declaration from the descriptor.","If you maintain the plugin, delete the `controller`/native-controller property from plugin-descriptor.properties and rebuild.","Do not attempt to bypass — the runtime forbids native controllers for non-system plugins."],"exampleFix":"# plugin-descriptor.properties\n# before\nelasticsearch.plugin.controller=true\n# after\n# (remove the line)","handlingStrategy":"validation","validationCode":"Properties p = new Properties();\np.load(Files.newInputStream(Path.of(pluginDescriptorPath)));\nif (\"true\".equalsIgnoreCase(p.getProperty(\"elasticsearch.plugin.controller\"))) {\n    throw new IllegalStateException(\"Plugin declares a native controller; not installable via CLI\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Do not set the controller property in plugin-descriptor.properties for distributable plugins.","Audit plugin descriptor templates copied from system internals before publishing."],"tags":["plugin-install","native-controller","descriptor","illegal-state","elasticsearch"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}