spring-projects/spring-boot · error · RuntimeException

Failed to read main class name from

Error message

Failed to read main class name from '{}'

What it means

Thrown by ResolveMainClassName.ClassNameReader.transform when Files.readString(output) throws an IOException while reading the temp file that holds the resolved main class name. The file is non-empty (it passed the length > 0 check at line 175), so the resolution task did write something, but the read-back failed at the filesystem level.

Solutions

  1. Run the build with '--no-daemon' and a clean build directory (gradle clean) to rule out daemon/process races.
  2. Move the Gradle build temporary directory to a stable local filesystem: set 'org.gradle.java.io.tmpdir' or GRADLE_OPTS.
  3. Disable or whitelist the build directory in antivirus/file-watcher tools.
  4. Check disk space and filesystem health if the error is persistent.
Defensive patterns

Strategy: retry

Validate before calling

// Before reading, confirm the file is still readable.
Path output = file.getAsFile().toPath();
if (!Files.isReadable(output)) {
    // re-trigger resolution or fail with a clearer message
    throw new IllegalStateException("Main class file not readable: " + output);
}

Try / catch

// Retry once on transient IOException, then surface a clear error.
String mainClass = null;
for (int attempt = 0; attempt < 2; attempt++) {
    try {
        mainClass = Files.readString(output);
        break;
    } catch (IOException ex) {
        if (attempt == 1) throw new RuntimeException("Main class file unreadable after retry: " + output, ex);
    }
}

Prevention

When it happens

Trigger: The main-class resolution file exists and is non-empty, but the JVM cannot read it: the file was deleted between the length check and the readString call, permissions changed, or the underlying filesystem returned an I/O error.

Common situations: Running on a flaky network filesystem (NFS, SMB) where temp files become inaccessible. Antivirus or file-watching software locking or deleting the temp file mid-build. Concurrent Gradle daemons or build processes racing on the same build directory. Disk corruption or the build directory being on a RAM disk that ran out of space.

Related errors


AI-assisted analysis of spring-projects/spring-boot@270dfe353f (2026-08-11). Data as JSON: /api/errors/6d69a7fdd92c09c6. Report an issue: GitHub.

Appendix: source

Thrown at build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/ResolveMainClassName.java:184

		private final String classpath;

		private ClassNameReader(String classpath) {
			this.classpath = classpath;
		}

		@Override
		public String transform(RegularFile file) {
			if (file.getAsFile().length() == 0) {
				throw new InvalidUserDataException(
						"Main class name has not been configured and it could not be resolved from classpath "
								+ this.classpath);
			}
			Path output = file.getAsFile().toPath();
			try {
				return Files.readString(output);
			}
			catch (IOException ex) {
				throw new RuntimeException("Failed to read main class name from '" + output + "'");
			}
		}

	}

}

View on GitHub (pinned to 270dfe353f)