awslabs/llrt · critical
fexecve failed
Error message
fexecve failed
What it means
main() finishes boot by exec'ing the freshly decompressed runtime with fexecve(outputFd, new_argv, environ), executing the binary held in the memfd. This error means fexecve returned (it only returns on failure), so the embedded runtime could not be started. The preceding logError notes the executable failed to start; this is the terminal abort.
Solutions
- Ensure /proc is mounted inside the container/chroot (fexecve needs /proc/self/fd): mount -t proc proc /proc.
- Adjust security policy to permit executing memfd files: SELinux boolean/policy (allow execmem/execveat), AppArmor profile, or remove `noexec` from the /proc mount.
- Use a Linux kernel with execveat support (>= 3.19) and a recent glibc/musl so fexecve works natively.
- Check for ENOENT from a missing ELF interpreter — use a statically linked llrt build if the target system lacks the dynamic loader.
- Run `strace -f -e trace=execveat,fexecve` to identify the exact errno, then address that specific denial.
Example fix
// before (chroot without proc) chroot /srv/box /usr/local/bin/llrt app.js // after mount -t proc proc /srv/box/proc && chroot /srv/box /usr/local/bin/llrt app.js
Defensive patterns
Strategy: validation
Validate before calling
// Verify the exec prerequisites before launching llrt:
import { existsSync, statSync } from 'node:fs';
function canExecMemfd() {
if (!existsSync('/proc/self/fd')) return false; // fexecve needs /proc
const st = statSync('/proc');
return true;
}
if (!canExecMemfd()) throw new Error('Mount /proc and ensure exec of memfd files is allowed'); Try / catch
try {
child_process.execFileSync('./llrt', ['app.js']);
} catch (e) {
if (e.status === 1 && /fexecve failed/.test(String(e.stderr))) {
// mount /proc, relax SELinux/noexec policy, or use a statically linked build, then retry
}
} Prevention
- Always mount /proc in containers/chroots where llrt runs.
- Avoid `noexec` on /proc and allow execveat/memfd execution in SELinux/AppArmor policies.
- Prefer statically linked llrt builds when target systems may lack the ELF dynamic loader.
- Diagnose with `strace -e trace=execveat` to capture the exact errno before changing policy.
When it happens
Trigger: fexecve fails with ENOENT (no interpreter for a PT_INTERP binary or /proc not mounted so the memfd /proc/self/fd path is unavailable), EACCES/EPERM (noexec mount policy via noexec /proc, SELinux denying memfd exec, `no_new_privs`/LSM rules), ENOMEM, or ETXTBSY in odd fd-flag states. Requires /proc mounted since fexecve relies on /proc/self/fd.
Common situations: Containers or chroots without /proc mounted, hardened Kubernetes/SELinux policies blocking execve of memfd files, `noexec` mounted /proc or /dev, old kernel/glibc without fexecve support, and security products that block anonymous-memory execution.
Related errors
AI-assisted analysis of awslabs/llrt@742fc00b82 (2026-09-12).
Data as JSON: /api/errors/1b239c0333adbd51.
Report an issue: GitHub.
Appendix: source
Thrown at llrt/src/main.c:337
if (memorySize > 2048)
{
memoryFactor = 0.95;
}
char mimallocReserveMemoryMb[16];
sprintf(mimallocReserveMemoryMb, "%iMiB", (int)(memorySize * memoryFactor));
setenv("_START_TIME", startTimeStr, false);
setenv("MIMALLOC_RESERVE_OS_MEMORY", mimallocReserveMemoryMb, false);
setenv("MIMALLOC_LIMIT_OS_ALLOC", "1", false);
logInfo("Starting app\n");
fexecve(outputFd, new_argv, environ);
logError("Failed to start executable");
err(1, "fexecve failed");
return 1;
}View on GitHub (pinned to 742fc00b82)