{"record":{"id":"0b0a8bdf01cfde85","repo":"elastic/elasticsearch","slug":"empty-location-for-plugin-id","errorCode":null,"errorMessage":"Empty location for plugin [{id}]","messagePattern":"Empty location for plugin \\[(.+?)\\]","errorType":"exception","errorClass":"PluginSyncException","httpStatus":null,"severity":"error","filePath":"distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/PluginsConfig.java","lineNumber":102,"sourceCode":"                );\n            }\n        }\n\n        if (this.proxy != null) {\n            final String[] parts = this.proxy.split(\":\");\n            if (parts.length != 2) {\n                throw new PluginSyncException(\"Malformed [proxy], expected [host:port] in [elasticsearch-plugins.yml]\");\n            }\n\n            if (ProxyUtils.validateProxy(parts[0], parts[1]) == false) {\n                throw new PluginSyncException(\"Malformed [proxy], expected [host:port] in [elasticsearch-plugins.yml]\");\n            }\n        }\n\n        for (InstallablePlugin p : plugins) {\n            if (p.getLocation() != null) {\n                if (p.getLocation().isBlank()) {\n                    throw new PluginSyncException(\"Empty location for plugin [\" + p.getId() + \"]\");\n                }\n\n                try {\n                    // This also accepts Maven coordinates\n                    new URI(p.getLocation());\n                } catch (URISyntaxException e) {\n                    throw new PluginSyncException(\"Malformed location for plugin [\" + p.getId() + \"]\");\n                }\n            }\n        }\n    }\n\n    public List<InstallablePlugin> getPlugins() {\n        return plugins;\n    }\n\n    public String getProxy() {\n        return proxy;","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/PluginsConfig.java#L84-L120","documentation":"Thrown by PluginsConfig.validate while iterating plugins that have a non-null location: if a location string is non-null but `isBlank()` (empty or whitespace only), it is rejected as PluginSyncException. This catches the gap where a plugin gets past the official/migrated check because location was set, but the value carries no usable content.","triggerScenarios":"For each plugin with `getLocation() != null`, the code runs `p.getLocation().isBlank()`; a blank location string throws with the plugin id in the message.","commonSituations":"YAML entry like `- id: x` then `location:` with no value (parses as empty string); location set to spaces or a stray newline; templating rendered an empty location placeholder.","solutions":["Provide a real location value (URL, file:// path, or Maven coordinate) for the plugin.","If the plugin is official/migrated, remove the `location:` key entirely so the null check at line 82 governs.","Lint the YAML so no `location:` resolves to an empty/whitespace string."],"exampleFix":"# before:\nplugins:\n  - id: custom-x\n    location:        # blank -> error\n# after (official plugin, drop location):\nplugins:\n  - id: analysis-icu\n# or (non-official, give a real value):\nplugins:\n  - id: custom-x\n    location: file:///opt/plugins/custom-x.zip","handlingStrategy":"validation","validationCode":"// Reject blank locations before validation.\nfor (InstallablePlugin p : parsed.getPlugins()) {\n    if (p.getLocation() != null && p.getLocation().isBlank()) {\n        throw new IllegalArgumentException(\"Plugin \" + p.getId() + \" has a blank location\");\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Template `location` only when a value exists; omit the key otherwise.","Lint the yml so no `location:` resolves to an empty string.","Treat blank and null location identically in pre-deploy checks."],"tags":["plugins-config","validation","yaml","plugin-cli"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}