apache/maven · error · XmlReaderException
Unable to read plugin:
Error message
Unable to read plugin:
What it means
Wrapper thrown when parsing a PluginDescriptor (plugin.xml) fails: malformed XML, strict-mode rejection of unknown elements, or IO errors while opening the path or URL. The underlying exception is preserved as the cause; STaX causes carry line and column information which the factory appends to the message.
Source
Thrown at impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultPluginXmlFactory.java:77
PluginDescriptorStaxReader xml = request.getTransformer() != null
? new PluginDescriptorStaxReader(request.getTransformer()::transform)
: new PluginDescriptorStaxReader();
xml.setAddDefaultEntities(request.isAddDefaultEntities());
if (inputStream != null) {
return xml.read(inputStream, request.isStrict());
} else if (reader != null) {
return xml.read(reader, request.isStrict());
} else if (path != null) {
try (InputStream is = Files.newInputStream(path)) {
return xml.read(is, request.isStrict());
}
} else {
try (InputStream is = url.openStream()) {
return xml.read(is, request.isStrict());
}
}
} catch (Exception e) {
throw new XmlReaderException("Unable to read plugin: " + getMessage(e), getLocation(e), e);
}
}
@Override
public void write(XmlWriterRequest<PluginDescriptor> request) throws XmlWriterException {
requireNonNull(request, "request");
PluginDescriptor content = requireNonNull(request.getContent(), "content");
Path path = request.getPath();
OutputStream outputStream = request.getOutputStream();
Writer writer = request.getWriter();
if (writer == null && outputStream == null && path == null) {
throw new IllegalArgumentException("writer, outputStream or path must be non null");
}
try {
if (writer != null) {
new PluginDescriptorStaxWriter().write(writer, content);
} else if (outputStream != null) {
new PluginDescriptorStaxWriter().write(outputStream, content);View on GitHub (pinned to e4093d4e12)
Solutions
- Read getCause() - XMLStreamException messages include the line and column of the failure
- Set .strict(false) on the request when unknown elements are expected and tolerable
- Validate the descriptor XML externally (xmllint) before passing it in
- For URL sources, fetch and inspect what the server actually returns before parsing
Example fix
// before
PluginDescriptor pd = pluginXmlFactory.read(XmlReaderRequest.builder()
.path(descriptorPath)
.build()); // strict default may reject unknown tags
// after
PluginDescriptor pd = pluginXmlFactory.read(XmlReaderRequest.builder()
.path(descriptorPath)
.strict(false)
.build()); Defensive patterns
Strategy: try-catch
Try / catch
try {
PluginDescriptor pd = pluginXmlFactory.read(req);
} catch (XmlReaderException e) {
Throwable cause = e.getCause();
// XMLStreamException: line/column of parse failure; IOException: unreadable source
log.error("plugin.xml invalid: {} at {}", e.getMessage(), e.getLocation(), cause);
} Prevention
- Use strict(false) when parsing descriptors from foreign plugin-tools versions
- Validate plugin.xml well-formedness before feeding it to the factory
- For URL sources, confirm the server returns XML, not an error page
When it happens
Trigger: Feeding a malformed or truncated plugin.xml; strict mode active while the descriptor contains elements unknown to the bundled descriptor model; an unreadable path or a URL whose openStream() fails.
Common situations: Reading plugin descriptors generated by a different maven-plugin-tools version than the runtime model expects; descriptors corrupted during packaging; URL sources behind proxies that return error pages instead of XML.
Related errors
- path, url, reader or inputStream must be non null
- writer, outputStream or path must be non null
- Unable to write plugin:
- Unable to read settings:
- Unable to read toolchains: {}
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/51cfbf2e9209e363.
Report an issue: GitHub.