iBotPeaches/Apktool · error · BrutException
could not exec:
Error message
could not exec:
What it means
Thrown by OS.exec when ProcessBuilder.start() raises IOException — the process was never created. Typical causes: the executable does not exist (message often 'Cannot run program ... No such file or directory'), is not executable, or the OS refused the spawn (fork limit, permission denied). The failed command array is included in the message and the IOException is the cause.
Source
Thrown at brut.j.util/src/main/java/brut/util/OS.java:150
cpfile(file, destFile);
}
}
}
public static void exec(String[] cmd) throws BrutException {
try {
ProcessBuilder builder = new ProcessBuilder(cmd);
Process ps = builder.start();
new StreamForwarder(ps.getErrorStream(), "ERROR").start();
new StreamForwarder(ps.getInputStream(), "OUTPUT").start();
int exitValue = ps.waitFor();
if (exitValue != 0) {
throw new BrutException("Execution failed (exit code = " + exitValue + "): " + Arrays.toString(cmd));
}
} catch (IOException ex) {
throw new BrutException("could not exec: " + Arrays.toString(cmd), ex);
} catch (InterruptedException ex) {
throw new BrutException("could not exec : " + Arrays.toString(cmd), ex);
}
}
public static String execAndReturn(String[] cmd) {
ExecutorService executor = Executors.newCachedThreadPool();
try {
ProcessBuilder builder = new ProcessBuilder(cmd);
builder.redirectErrorStream(true);
Process process = builder.start();
StreamCollector collector = new StreamCollector(process.getInputStream());
executor.execute(collector);
process.waitFor(15, TimeUnit.SECONDS);
executor.shutdownNow();
if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {View on GitHub (pinned to 79b63384d7)
Solutions
- Verify the executable resolves and is runnable before exec: new File(cmd[0]).canExecute() or 'which <bin>'
- chmod +x the extracted binary after pulling it out of the jar (Jar extraction does not preserve the exec bit)
- Use an absolute path to the binary instead of relying on PATH, and confirm no unquoted spaces in each argv element
- On 64-bit-only systems, install 32-bit compatibility libs or point to a 64-bit build of the tool
Example fix
// before
OS.exec(new String[]{"/tmp/BRUT123/aapt", "v"}); // IOException: cannot run program
// after
File bin = new File("/tmp/BRUT123/aapt");
if (!bin.canExecute() && !bin.setExecutable(true)) {
throw new BrutException("Cannot make executable: " + bin);
}
OS.exec(new String[]{bin.getAbsolutePath(), "v"}); Defensive patterns
Strategy: validation
Validate before calling
void ensureExecutable(String binPath) throws IOException {
File bin = new File(binPath);
if (!bin.isFile()) throw new FileNotFoundException(binPath);
if (!bin.canExecute() && !bin.setExecutable(true)) {
throw new IOException("cannot mark executable: " + binPath);
}
}
// ensureExecutable(cmd[0]); OS.exec(cmd); Try / catch
try {
OS.exec(cmd);
} catch (BrutException e) {
if (e.getCause() instanceof IOException
&& e.getCause().getMessage().contains("No such file")) {
// binary missing: fix PATH or extraction, not retryable
throw new EnvironmentException("tool not found: " + cmd[0], e);
}
throw e;
} Prevention
- Set the execute bit right after extracting binaries from jars
- Prefer absolute binary paths over PATH lookup in CI and containers
- Keep each argv element free of embedded spaces, or quote at the ProcessBuilder-array level (never string-join)
When it happens
Trigger: OS.exec(cmd) where cmd[0] names a binary not on PATH or at a wrong absolute path, the file lacks the execute bit, or it is a directory; also spawn failures such as EMFILE/ENOMEM under heavy load.
Common situations: Extracted native helper (aapt and friends) not marked +x or extracted to a path containing spaces that was not quoted in argv; PATH differs in CI/containers versus local shell; 32-bit binary on a 64-bit-only image; running on a JRE without the required exec permission in sandboxed environments.
Related errors
- Execution failed (exit code =
- could not exec :
- Could not create tmp dir
- aapt2 binaries are not available for 32-bit platforms.
- Could not identify platform: " + OSDetection.returnOS()
AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14).
Data as JSON: /api/errors/29f1f8733209c871.
Report an issue: GitHub.