spring-projects/spring-boot · error · RuntimeException
Failed to get dir mode from CopySpec
Error message
Failed to get dir mode from CopySpec
What it means
Thrown by BootArchiveSupport.getDirMode() when reflective invocation of CopySpec.getDirMode() fails. This reflection path is only used on Gradle < 8.3 (the dirPermissions API is used on 8.3+). Since the plugin requires Gradle 8.14+, this code path is unreachable in supported setups; encountering it means an unsupported Gradle or a non-standard CopySpec during bootJar/bootWar archive creation.
Source
Thrown at build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootArchiveSupport.java:158
return (GradleVersion.current().compareTo(GradleVersion.version("8.3")) >= 0)
? asUnixNumeric(copySpec.getDirPermissions()) : getDirMode(copySpec);
}
private @Nullable Integer getUnixNumericFilePermissions(CopySpec copySpec) {
return (GradleVersion.current().compareTo(GradleVersion.version("8.3")) >= 0)
? asUnixNumeric(copySpec.getFilePermissions()) : getFileMode(copySpec);
}
private @Nullable Integer asUnixNumeric(Property<ConfigurableFilePermissions> permissions) {
return permissions.isPresent() ? permissions.get().toUnixNumeric() : null;
}
private @Nullable Integer getDirMode(CopySpec copySpec) {
try {
return (Integer) copySpec.getClass().getMethod("getDirMode").invoke(copySpec);
}
catch (Exception ex) {
throw new RuntimeException("Failed to get dir mode from CopySpec", ex);
}
}
private @Nullable Integer getFileMode(CopySpec copySpec) {
try {
return (Integer) copySpec.getClass().getMethod("getFileMode").invoke(copySpec);
}
catch (Exception ex) {
throw new RuntimeException("Failed to get file mode from CopySpec", ex);
}
}
private boolean isUsingDefaultLoader(Jar jar) {
return DEFAULT_LAUNCHER_CLASSES.contains(jar.getManifest().getAttributes().get("Main-Class"));
}
void requiresUnpack(String... patterns) {
this.requiresUnpack.include(patterns);View on GitHub (pinned to 5b2dbdbb8b)
Solutions
- Upgrade Gradle to 8.14 or later so getDirPermissions().toUnixNumeric() is used instead.
- Verify GradleVersion.current() is not being spoofed by a malformed gradle-runtime.
- Ensure any custom CopySpec passed into bootJar/bootWar is a standard Gradle implementation.
Example fix
// gradle/wrapper/gradle-wrapper.properties // before: // distributionUrl=...gradle-8.2-bin.zip // after: // distributionUrl=...gradle-8.14-bin.zip
Defensive patterns
Strategy: validation
Validate before calling
import org.gradle.util.GradleVersion
require(GradleVersion.current() >= GradleVersion.version("8.3")) {
"Boot archive file/dir mode requires Gradle 8.3+ (use 8.14+)"
}
Prevention
- Run Gradle 8.14+ to use the modern dirPermissions API.
- Avoid injecting non-standard CopySpec instances into bootJar/bootWar.
When it happens
Trigger: getUnixNumericDirPermissions() routes to getDirMode() only when GradleVersion.current() < 8.3; the reflective getMethod("getDirMode").invoke(copySpec) throws, wrapped as RuntimeException at line 158.
Common situations: Running an unsupported old Gradle; a custom CopySpec injected into the boot archive that lacks getDirMode; JVM module restrictions blocking reflection on Gradle internals.
Related errors
- Failed to get file mode from CopySpec
- Failed to get mode from FileCopyDetails
- Failed to set file mode on CopySpec
- Spring Boot plugin requires Gradle 8.x (8.14 or later) or 9.
- Failed to create {}
AI-assisted analysis of spring-projects/spring-boot@5b2dbdbb8b (2026-08-04).
Data as JSON: /data/errors/36c7b74ebae27dcc.json.
Report an issue: GitHub.