apache/maven · error · XmlWriterException
Unable to write plugin:
Error message
Unable to write plugin:
What it means
Wrapper thrown by DefaultPluginXmlFactory.write when serializing a PluginDescriptor fails: STaX writer errors or IOException while opening and writing the target path. The real failure is preserved as the cause and its message and location are appended.
Solutions
- Unwrap getCause() to see the actual IOException or XMLStreamException
- Run Files.createDirectories(path.getParent()) before the write
- Verify write permission on the target directory in the failing environment
Example fix
// before
pluginXmlFactory.write(XmlWriterRequest.builder()
.content(descriptor)
.path(outputDir.resolve("plugin.xml"))
.build());
// after
Files.createDirectories(outputDir);
pluginXmlFactory.write(XmlWriterRequest.builder()
.content(descriptor)
.path(outputDir.resolve("plugin.xml"))
.build()); Defensive patterns
Strategy: try-catch
Try / catch
try {
pluginXmlFactory.write(req);
} catch (XmlWriterException e) {
if (e.getCause() instanceof IOException io) {
// create parent directories / fix permissions, then retry once
} else {
throw e;
}
} Prevention
- Create output directories during build preparation, not during writes
- Verify write permissions of the target directory in CI before the build starts
When it happens
Trigger: Writing a descriptor to a path whose parent directory does not exist or is not writable; XMLStreamWriter failures; disk-full conditions during the write.
Common situations: Regenerating plugin.xml into a build output directory that does not exist yet; read-only source trees in CI sandboxes.
Related errors
- Unable to write model:
- Unable to write settings
- Unable to write toolchains
- path, url, reader or inputStream must be non null
- Problem during inlining POM
AI-assisted analysis of apache/maven@e4093d4e12 (2026-08-21).
Data as JSON: /api/errors/2ab6aa1ada87b998.
Report an issue: GitHub.
Appendix: source
Thrown at impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultPluginXmlFactory.java:102
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);
} else {
try (OutputStream os = Files.newOutputStream(path)) {
new PluginDescriptorStaxWriter().write(os, content);
}
}
} catch (Exception e) {
throw new XmlWriterException("Unable to write plugin: " + getMessage(e), getLocation(e), e);
}
}
/**
* Simply parse the given xml string.
*
* @param xml the input XML string
* @return the parsed object
* @throws XmlReaderException if an error occurs during the parsing
* @see #toXmlString(Object)
*/
public static PluginDescriptor fromXml(@Nonnull String xml) throws XmlReaderException {
return new DefaultPluginXmlFactory().fromXmlString(xml);
}
/**
* Simply converts the given content to an XML string.
*View on GitHub (pinned to e4093d4e12)