junit-team/junit5 · error · UncheckedIOException

Failed to create output file: %s

Error message

Failed to create output file: %s

What it means

Thrown as an UncheckedIOException by OutputDir.createFile(prefix, extension) when either Files.delete() on a pre-existing same-named file or Files.createFile() on the generated path fails. The filename is '{prefix}-{randomLong}.{extension}' where the randomLong comes from a SecureRandom, so collisions are essentially impossible — the failure is almost always environmental. This is an INTERNAL API.

Source

Thrown at junit-platform-launcher/src/main/java/org/junit/platform/launcher/listeners/OutputDir.java:114

		this.random = random;
	}

	public Path toPath() {
		return path;
	}

	public Path createFile(String prefix, String extension) throws UncheckedIOException {
		String filename = "%s-%d.%s".formatted(prefix, positiveLong(random), extension);
		Path outputFile = path.resolve(filename);

		try {
			if (Files.exists(outputFile)) {
				Files.delete(outputFile);
			}
			return Files.createFile(outputFile);
		}
		catch (IOException e) {
			throw new UncheckedIOException("Failed to create output file: " + outputFile, e);
		}
	}

	private static long positiveLong(SecureRandom random) {
		var value = random.nextLong();
		if (value == Long.MIN_VALUE) {
			// ensure Math.abs returns positive value
			value++;
		}
		return Math.abs(value);
	}

	/**
	 * Determine if the supplied directory contains files with any of the
	 * supplied extensions.
	 */
	private static boolean containsFilesWithExtensions(Path dir, String... extensions) throws IOException {
		BiPredicate<Path, BasicFileAttributes> matcher = (path, basicFileAttributes) -> {

View on GitHub (pinned to f070c699a0)

Solutions

  1. Verify Files.isWritable(outputDir.toPath()) still holds at the point of failure and re-run.
  2. Move the output directory to a local non-network volume (e.g. /tmp or the OS temp dir).
  3. Configure antivirus/search indexer to skip the JUnit output directory.
  4. If using parallel forks, give each fork a distinct output dir via the {uniqueNumber} placeholder in junit.platform.reporting.output.dir.
Defensive patterns

Strategy: try-catch

Validate before calling

// Before calling createFile, confirm the directory is still writable.
Path dir = outputDir.toPath();
if (!Files.isDirectory(dir) || !Files.isWritable(dir)) {
    throw new IllegalStateException("Output directory not writable: " + dir);
}

Try / catch

try {
    Path report = outputDir.createFile("events", "xml");
} catch (UncheckedIOException e) {
    // The IOException cause tells you why (read-only, full disk, lock).
    log.warn("Could not create report file in {}", outputDir.toPath(), e.getCause());
}

Prevention

When it happens

Trigger: Calling outputDir.createFile(...) when the output directory has become read-only between OutputDir creation and the call; the directory was deleted mid-run; the underlying volume is full; on Windows another process (antivirus, search indexer, another fork) holds an exclusive lock on the generated file; the path is on a network filesystem that dropped.

Common situations: Antivirus or Windows Defender scanning newly created files and briefly locking them; parallel Gradle/Maven forks writing to the same shared output directory; a CI cleanup job wiping the output dir during the run; an NFS/SMB mount with a transient outage; disk exhaustion during a long test suite.

Related errors


AI-assisted analysis of junit-team/junit5@f070c699a0 (2026-08-11). Data as JSON: /api/errors/8d7c17875e643fed. Report an issue: GitHub.