spring-projects/spring-boot · error · RuntimeException
Failed to get mode from FileCopyDetails
Error message
Failed to get mode from FileCopyDetails
What it means
Thrown by BootZipCopyAction's getMode, which reflectively invokes FileCopyDetails.getMode() on the legacy path for Gradude versions below 8.3 (the caller checks GradleVersion 8.3 and uses details.getPermissions().toUnixNumeric() on modern Gradle, falling back to getMode otherwise). Any reflection exception — NoSuchMethodException, IllegalAccessException, InvocationTargetException — is wrapped in a RuntimeException.
Solutions
- Upgrade Gradle to 8.3+ so the modern getPermissions().toUnixNumeric() path is used.
- Remove any plugin that replaces FileCopyDetails implementations.
- If pinned to old Gradle, downgrade the Spring Boot plugin to a compatible version.
Example fix
// before: Gradle 7.x uses reflective getMode // after: upgrade wrapper distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip
Defensive patterns
Strategy: validation
Validate before calling
// Gate on Gradle 8.3+ to use the modern permissions API.
if (GradleVersion.current().compareTo(GradleVersion.version("8.3")) < 0) {
throw new GradleException("Upgrade to Gradle 8.3+ to avoid reflective getMode.")
} Prevention
- Use Gradle 8.3+ (preferably 8.14+) via the wrapper.
- Do not replace FileCopyDetails with custom implementations.
- Keep Gradle and Spring Boot plugin versions aligned.
When it happens
Trigger: Building a boot archive on Gradle < 8.3 where FileCopyDetails lacks a getMode() method or the method throws during invocation. The modern path (details.getPermissions().toUnixNumeric()) is only taken on 8.3+.
Common situations: Running on an old Gradle version (< 8.3). A custom FileCopyDetails implementation that hides getMode(). Co-occurs with errors [5] and [6] as part of the same legacy-permissions reflection cluster.
Related errors
- Failed to get dir mode from CopySpec
- Failed to get file mode from CopySpec
- Failed to set file mode on CopySpec
- Failed to add to
- Failed to create
AI-assisted analysis of spring-projects/spring-boot@270dfe353f (2026-08-11).
Data as JSON: /api/errors/a92f5afc04e2fbd9.
Report an issue: GitHub.
Appendix: source
Thrown at build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootZipCopyAction.java:485
return (BootZipCopyAction.this.dirMode != null) ? BootZipCopyAction.this.dirMode : getPermissions(details);
}
private int getFileMode(FileCopyDetails details) {
return (BootZipCopyAction.this.fileMode != null) ? BootZipCopyAction.this.fileMode
: getPermissions(details);
}
private int getPermissions(FileCopyDetails details) {
return (GradleVersion.current().compareTo(GradleVersion.version("8.3")) >= 0)
? details.getPermissions().toUnixNumeric() : getMode(details);
}
private int getMode(FileCopyDetails details) {
try {
return (int) details.getClass().getMethod("getMode").invoke(details);
}
catch (Exception ex) {
throw new RuntimeException("Failed to get mode from FileCopyDetails", ex);
}
}
}
/**
* Callback interface used to customize a {@link ZipArchiveEntry}.
*/
@FunctionalInterface
private interface ZipEntryCustomizer {
ZipEntryCustomizer NONE = (entry) -> {
};
/**
* Customize the entry.
* @param entry the entry to customize
* @throws IOException on IO errorView on GitHub (pinned to 270dfe353f)