{"record":{"id":"cc4007da2a4b5fa9","repo":"elastic/elasticsearch","slug":"malformed-location-for-plugin-id","errorCode":null,"errorMessage":"Malformed location for plugin [{id}]","messagePattern":"Malformed 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":109,"sourceCode":"                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;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) {\n            return true;\n        }","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/PluginsConfig.java#L91-L127","documentation":"Thrown by PluginsConfig.validate when a plugin location is present and non-blank but cannot be parsed as a URI. The code wraps `new URI(p.getLocation())` and rethrows URISyntaxException as PluginSyncException. The comment notes Maven coordinates are also accepted (URI is lenient for those), so a genuine syntax failure means a malformed URL or path.","triggerScenarios":"For each plugin with a non-blank location, `new URI(location)` is attempted; if it throws URISyntaxException (illegal characters, bad scheme, unescaped spaces), the wrapper PluginSyncException is thrown with the plugin id.","commonSituations":"File path with unencoded spaces (`file:///opt/my plugins/x.zip`); URL with illegal characters; missing scheme on what should be a URL; Windows path with backslashes used where a URI is required.","solutions":["URL-encode the location, especially spaces: `file:///opt/my%20plugins/x.zip`.","Use a proper scheme (http://, https://, file://) or a valid Maven coordinate (`group:artifact:version`).","Test the value parses as a URI before deploy: `python -c \"import sys,urllib.parse; print(urllib.parse.quote(sys.argv[1]))\"`."],"exampleFix":"# before:\nplugins:\n  - id: custom-x\n    location: file:///opt/my plugins/x.zip   # space breaks URI\n# after:\nplugins:\n  - id: custom-x\n    location: file:///opt/my%20plugins/x.zip","handlingStrategy":"validation","validationCode":"// Pre-validate that each location parses as a URI.\nfor (InstallablePlugin p : parsed.getPlugins()) {\n    String loc = p.getLocation();\n    if (loc != null && !loc.isBlank()) {\n        try { new URI(loc); } catch (URISyntaxException ex) {\n            throw new IllegalArgumentException(\"Bad location for \" + p.getId() + \": \" + loc, ex);\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["URL-encode spaces and special characters in file paths.","Prefer https:// URLs or Maven coordinates over raw filesystem paths.","Test the location string parses as URI in CI before deploy."],"tags":["plugins-config","validation","uri","yaml","plugin-cli"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}