elastic/elasticsearch · error · PluginSyncException
Malformed location for plugin [{id}]
Error message
Malformed location for plugin [{id}] What it means
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.
Source
Thrown at distribution/tools/plugin-cli/src/main/java/org/elasticsearch/plugins/cli/PluginsConfig.java:109
throw new PluginSyncException("Malformed [proxy], expected [host:port] in [elasticsearch-plugins.yml]");
}
if (ProxyUtils.validateProxy(parts[0], parts[1]) == false) {
throw new PluginSyncException("Malformed [proxy], expected [host:port] in [elasticsearch-plugins.yml]");
}
}
for (InstallablePlugin p : plugins) {
if (p.getLocation() != null) {
if (p.getLocation().isBlank()) {
throw new PluginSyncException("Empty location for plugin [" + p.getId() + "]");
}
try {
// This also accepts Maven coordinates
new URI(p.getLocation());
} catch (URISyntaxException e) {
throw new PluginSyncException("Malformed location for plugin [" + p.getId() + "]");
}
}
}
}
public List<InstallablePlugin> getPlugins() {
return plugins;
}
public String getProxy() {
return proxy;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}View on GitHub (pinned to db6a809a66)
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]))"`.
Example fix
# before:
plugins:
- id: custom-x
location: file:///opt/my plugins/x.zip # space breaks URI
# after:
plugins:
- id: custom-x
location: file:///opt/my%20plugins/x.zip Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate that each location parses as a URI.
for (InstallablePlugin p : parsed.getPlugins()) {
String loc = p.getLocation();
if (loc != null && !loc.isBlank()) {
try { new URI(loc); } catch (URISyntaxException ex) {
throw new IllegalArgumentException("Bad location for " + p.getId() + ": " + loc, ex);
}
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Cannot have null or empty IDs in [elasticsearch-plugins.yml]
- Duplicate plugin ID [{id}] found in [elasticsearch-plugins.y
- Must specify location for non-official plugin [{id}] in [ela
- Malformed [proxy], expected [host:port] in [elasticsearch-pl
- Empty location for plugin [{id}]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/cc4007da2a4b5fa9.
Report an issue: GitHub.