spring-projects/spring-boot · error · GradleException
Failed to read
Error message
Failed to read '{}' What it means
Thrown by ApplicationPluginAction.loadResource when an IOException occurs while reading a bundled classpath resource (e.g. a default start-script template) character-by-character into a StringWriter. The resource was located successfully (getResourceAsStream returned non-null, otherwise Assert.state would fire first), but the read loop itself failed partway. This is an internal plugin resource read, not a user file.
Solutions
- Clean and refresh the Gradle dependencies: run 'gradle --refresh-dependencies' to re-download a non-corrupt spring-boot-gradle-plugin JAR.
- Clear the Gradle caches for the plugin: remove ~/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-gradle-plugin and re-resolve.
- Verify the plugin JAR is not being shadowed or modified by a custom ClassLoader or fat-JAR packaging in the build.
- Check for filesystem-level issues (disk full, NFS hiccup) if the error appears intermittently.
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check that the resource exists and is openable before the read loop.
// Note: this guards resource presence, not read-time I/O failures.
try (var probe = getClass().getResourceAsStream(name)) {
if (probe == null) {
throw new IllegalStateException("Resource not found: " + name);
}
} catch (IOException ex) {
// resource unreadable even for a probe — abort early
} Try / catch
// Recommended: catch GradleException around task execution and surface the cause.
try {
project.getTasks().named("startScripts").get().getActions().forEach(a -> a.execute(task));
} catch (GradleException ex) {
if (ex.getMessage() != null && ex.getMessage().startsWith("Failed to read '")) {
// handle corrupted plugin resource — refresh dependencies
throw new GradleException("Plugin resource unreadable. Run 'gradle --refresh-dependencies'.", ex);
}
throw ex;
} Prevention
- Pin the Spring Boot plugin version explicitly to avoid pulling a corrupt SNAPSHOT.
- Use 'gradle --refresh-dependencies' after plugin upgrades to re-fetch JARs.
- Avoid modifying or shading the spring-boot-gradle-plugin JAR at runtime.
When it happens
Trigger: Calling any Gradle task that triggers ApplicationPluginAction configuration (e.g. startScripts, installDist) when the JVM experiences an I/O interruption while reading the plugin's own bundled resource. The try-with-resources InputStreamReader.read(buffer) throws IOException inside the while loop.
Common situations: A corrupted or truncated plugin JAR (resource present in the index but unreadable), a custom ClassLoader that returns a broken stream, JVM running low on file descriptors, or the plugin JAR being replaced/modified while Gradle is still running. Extremely rare in normal operation since the resource is packaged inside the plugin itself.
Related errors
- Failed to add to
- Failed to create
- Failed to read main class name from
- Main class name has not been configured and it could not be…
- Spring Boot plugin requires Gradle 8.x (8.14 or later) or…
AI-assisted analysis of spring-projects/spring-boot@270dfe353f (2026-08-11).
Data as JSON: /api/errors/7b3de5608b551d21.
Report an issue: GitHub.
Appendix: source
Thrown at build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/ApplicationPluginAction.java:125
}
@Override
public Class<? extends Plugin<Project>> getPluginClass() {
return ApplicationPlugin.class;
}
private String loadResource(String name) {
try (InputStreamReader reader = new InputStreamReader(getResourceAsStream(name))) {
char[] buffer = new char[4096];
int read;
StringWriter writer = new StringWriter();
while ((read = reader.read(buffer)) > 0) {
writer.write(buffer, 0, read);
}
return writer.toString();
}
catch (IOException ex) {
throw new GradleException("Failed to read '" + name + "'", ex);
}
}
private InputStream getResourceAsStream(String name) {
InputStream stream = getClass().getResourceAsStream(name);
Assert.state(stream != null, "Resource '%s' not found'".formatted(name));
return stream;
}
private void configureFilePermissions(CopySpec copySpec, int mode) {
if (GradleVersion.current().compareTo(GradleVersion.version("8.3")) >= 0) {
copySpec.filePermissions((filePermissions) -> filePermissions.unix(Integer.toString(mode, 8)));
}
else {
configureFileMode(copySpec, mode);
}
}
View on GitHub (pinned to 270dfe353f)