junit-team/junit5 · error · JUnitException
Failed to create XML events file
Error message
Failed to create XML events file
What it means
Thrown as a JUnitException by OpenTestReportGeneratingListener.createDocumentWriter() (orElseGet branch) when Events.createDocumentWriter() fails to create or write the open-test-report.xml file under the root output directory. This is the DEFAULT transport — it fires only when junit.platform.reporting.open.xml.socket is NOT set. The output directory comes from TestPlan.getOutputDirectoryCreator().getRootDirectory(), which honors junit.platform.reporting.output.dir. Normally surfaces wrapped as error 145.
Solutions
- Set junit.platform.reporting.output.dir to a writable absolute path, e.g. -Djunit.platform.reporting.output.dir=/tmp/junit-reports.
- Confirm Files.isWritable(root) on the directory returned by the OutputDirectoryCreator before the run.
- Free disk space on the volume hosting the output directory.
- Disable any process that locks files in the output directory (search indexers, AV) or move the output off a network mount.
Example fix
// before -Djunit.platform.reporting.output.dir=/readonly/build/reports // after -Djunit.platform.reporting.output.dir=/var/tmp/junit-reports
Defensive patterns
Strategy: validation
Validate before calling
// Preflight: confirm the creator's root directory is writable before launch.
Path root = testPlan.getOutputDirectoryCreator().getRootDirectory();
if (!Files.isDirectory(root) || !Files.isWritable(root)) {
throw new IllegalStateException(
"XML events root directory not writable: " + root);
} Try / catch
try {
launcher.execute(request);
} catch (JUnitException e) {
if ("Failed to create XML events file".equals(e.getMessage())) {
Throwable cause = e.getCause();
// Resolve output dir and either fix permissions or switch junit.platform.reporting.output.dir.
} else {
throw e;
}
} Prevention
- Set junit.platform.reporting.output.dir to an absolute, writable, local path.
- Add a preflight Files.isWritable check on the OutputDirectoryCreator root in CI.
- Keep the volume under the output directory stable and non-full for the whole run.
- Avoid regular files shadowing the open-test-report.xml path.
When it happens
Trigger: The root output directory is read-only, has been deleted, or lives on a full volume at testPlanExecutionStarted time; Events.createDocumentWriter() cannot open the XML file for writing because a file lock is held by another process; the path is on a network mount that dropped; the directory creation succeeded earlier but the volume became unwritable.
Common situations: Read-only container layer for the default build/target dir; CI workspace cleaned between phases; antivirus locking the new XML file on Windows; NFS outage; junit.platform.reporting.output.dir pointing at a path whose parent is not writable.
Related errors
- Failed to create output dir
- Failed to create output file
- Failed to close XML events file
- Error redirecting stderr to file
- Error redirecting stdout and stderr to file
AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11).
Data as JSON: /api/errors/55c2760bc913d776.
Report an issue: GitHub.
Appendix: source
Thrown at junit-platform-reporting/src/main/java/org/junit/platform/reporting/open/xml/OpenTestReportGeneratingListener.java:167
NamespaceRegistry namespaceRegistry) throws Exception {
return config.get(SOCKET_PROPERTY_NAME, Integer::valueOf) //
.map(port -> {
try {
Socket socket = new Socket(InetAddress.getLoopbackAddress(), port);
Writer writer = new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8);
return Events.createDocumentWriter(namespaceRegistry, writer);
}
catch (Exception e) {
throw new JUnitException("Failed to connect to socket on port " + port, e);
}
}) //
.orElseGet(() -> {
try {
Path eventsXml = requireNonNull(outputDir).resolve("open-test-report.xml");
return Events.createDocumentWriter(namespaceRegistry, eventsXml);
}
catch (Exception e) {
throw new JUnitException("Failed to create XML events file", e);
}
});
}
private boolean isEnabled(ConfigurationParameters config) {
return config.getBoolean(ENABLED_PROPERTY_NAME).orElse(false);
}
private boolean isGitEnabled(ConfigurationParameters config) {
return config.getBoolean(GIT_ENABLED_PROPERTY_NAME).orElse(false);
}
@SuppressWarnings("EmptyCatch")
private void reportInfrastructure(ConfigurationParameters config) {
eventsFileWriter.append(infrastructure(), infrastructure -> {
try {
String hostName = InetAddress.getLocalHost().getHostName();
infrastructure.append(hostName(hostName));View on GitHub (pinned to f070c699a0)