quarkusio/quarkus · error · CodeGenFailureException
failed to set file: ${script} executable. Protoc invocation
Error message
failed to set file: ${script} executable. Protoc invocation may fail What it means
After writing the quarkus-grpc wrapper script, writeScript calls File.setExecutable(true); if the OS cannot set the execute bit it throws GrpcCodeGenFailureException with this message, warning that the subsequent protoc invocation will likely fail. Note it is a GrpcCodeGenFailureException, not CodeGenException.
Source
Thrown at extensions/grpc/codegen/src/main/java/io/quarkus/grpc/codegen/GrpcCodeGen.java:599
return writeScript(buildDir, pluginPath, "#!/bin/sh\n", ".sh");
} else {
return writeScript(buildDir, pluginPath, "@echo off\r\n", ".cmd");
}
}
private static Path writeScript(Path buildDir, Path pluginPath, String shebang, String suffix) throws CodeGenException {
Path script;
try {
script = Files.createTempFile(buildDir, "quarkus-grpc", suffix);
try (BufferedWriter writer = Files.newBufferedWriter(script)) {
writer.write(shebang);
writePluginExeCmd(pluginPath, writer);
}
} catch (IOException e) {
throw new CodeGenException("Failed to create a wrapper script for quarkus-grpc plugin", e);
}
if (!script.toFile().setExecutable(true)) {
throw new CodeGenFailureException("failed to set file: " + script + " executable. Protoc invocation may fail");
}
return script;
}
private static void writePluginExeCmd(Path pluginPath, BufferedWriter writer) throws IOException {
writer.write("\"" + io.smallrye.common.process.ProcessUtil.pathOfJava().toString() + "\" -cp \"" +
pluginPath.toAbsolutePath() + "\" " + quarkusProtocPluginMain);
writer.newLine();
}
private static boolean containsQuarkusKotlin(Collection<ResolvedDependency> dependencies) {
return dependencies.stream().anyMatch(new Predicate<ResolvedDependency>() {
@Override
public boolean test(ResolvedDependency rd) {
return rd.getGroupId().equalsIgnoreCase("io.quarkus")
&& rd.getArtifactId().equalsIgnoreCase("quarkus-kotlin");
}
});View on GitHub (pinned to e1c734241f)
Solutions
- Move the build to a filesystem supporting execute bits (Linux ext4/overlayfs, WSL native home dir instead of /mnt/c)
- Remount the volume without noexec (mount -o remount,exec or drop noexec from fstab/docker volume options)
- Run the build inside a container with exec permissions on the workspace mount
- If on Windows, confirm the failure is benign for .cmd files — but prefer building in a Linux container to avoid it
Example fix
# before docker run -v $(pwd):/project:noexec quarkus-build # after docker run -v $(pwd):/project quarkus-build
Defensive patterns
Strategy: validation
Validate before calling
// probe exec-bit support in the build directory before codegen
Path probe = buildDir.resolve(".exec-probe.sh");
Files.writeString(probe, "#!/bin/sh\n");
if (!probe.toFile().setExecutable(true)) {
throw new IllegalStateException("Cannot set exec bit on " + buildDir + " — noexec mount? Move the build directory.");
}
Files.deleteIfExists(probe); Try / catch
try {
build.run();
} catch (GrpcCodeGenFailureException e) {
if (e.getMessage().contains("failed to set file")) {
throw new IllegalStateException("Build dir lacks exec permission support; remount without noexec or move workspace", e);
}
} Prevention
- Avoid mounting build workspaces with :noexec in Docker or fstab
- In WSL, keep projects under the Linux filesystem (~/...), not /mnt/c
- Check NFS/SMB mount options (noexec, root_squash) before CI setup
- Prefer building in a standard Linux container with exec-capable overlayfs
When it happens
Trigger: Code generation where the newly created .sh/.cmd wrapper script lives on a filesystem that rejects execute permissions — noexec mounts, NTFS/FAT via WSL /mnt/c, NFS/SMB shares, Windows FAT-formatted drives.
Common situations: noexec Docker volume mounts for the build directory; WSL working on /mnt/c; network home directories (NFS with root_squash/noexec); CI tmpfs with noexec.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- Failed to make the file executable: ${exe}
- Failed to create directory: " + protoOutputDir
- Failed to extract proto file" + path + " to target: " + outP
- Failed to copy file: ${artifactPath} to ${exe}
- Failed to create a wrapper script for quarkus-grpc plugin
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/56acee57c43bfa00.
Report an issue: GitHub.