awslabs/llrt · critical
Failed to set file size
Error message
Failed to set file size
What it means
During decompression of the embedded (self-extracted) payload, llrt calls ftruncate(outputFd, *uncompressedSize) to pre-size the output memfd to the expected uncompressed size before mmap'ing it. This err(1) means the ftruncate syscall returned -1, so the output file could not be sized. Without a correctly sized file the subsequent shared mmap of the decompressed data is impossible, so the runtime aborts immediately.
Solutions
- Check sandbox/seccomp/container settings and allow the ftruncate syscall (e.g. adjust seccomp profile or AppArmor/SELinux policy).
- Verify the kernel is Linux with memfd/ftruncate support; run on a standard glibc/musl Linux environment.
- Rebuild llrt with debugging (logInfo) to confirm the memfd_create_syscall succeeded and outputFd is valid.
- Check RLIMIT_FSIZE (ulimit -f) is not set to 0 for the process.
Defensive patterns
Strategy: validation
Validate before calling
// Before deploying, smoke-test the binary in the target environment:
// it must run in a sandbox allowing ftruncate on memfd.
import { execFileSync } from 'node:child_process';
try {
execFileSync('./llrt', ['-v'], { stdio: 'ignore' });
} catch (e) {
throw new Error('llrt cannot start here (ftruncate/memfd blocked): ' + e.message);
} Try / catch
// err(1) exits the process — it cannot be caught inside llrt.
// Catch at the supervisor level:
try {
child_process.execFileSync('./llrt', ['app.js']);
} catch (e) {
if (e.status === 1 && /Failed to set file size/.test(String(e.stderr))) {
// fall back to a non-self-extracting runtime or fix the sandbox
}
} Prevention
- Smoke-test the binary inside the actual container/sandbox image before shipping.
- Keep seccomp/AppArmor profiles permissive enough for memfd + ftruncate.
- Avoid ulimit -f 0 and other restrictive rlimits for the process.
- Prefer standard Linux kernels with full memfd support.
When it happens
Trigger: ftruncate on the memfd created in main fails — practically only when the file descriptor outputFd is invalid (memfd creation silently broken), the fd was closed, or the process hits RLIMIT_FSIZE / runs on a filesystem or kernel lacking ftruncate support for the fd. Triggered by running the binary at all, since decompress() is called from main before any user code.
Common situations: Running the llrt binary in a hardened sandbox (seccomp filter blocking ftruncate), inside containers with restricted syscall allowlists, or on exotic kernels/fork servers where fd 0-state is manipulated before entry. Extremely rare on normal Linux.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- Could not create memfd
- Memory mapping failed: Unable to map %u bytes. Make sure…
- failed to decompress
- Failed to unmap memory
- fexecve failed
AI-assisted analysis of awslabs/llrt@742fc00b82 (2026-09-12).
Data as JSON: /api/errors/9591829ac519bf6e.
Report an issue: GitHub.
Appendix: source
Thrown at llrt/src/main.c:205
char *uncompressed;
uint8_t *compressedData;
pthread_t threads[parts];
if (parts > 1)
{
logInfo("Decompressing using %d threads\n", parts);
}
else
{
logInfo("Decompressing\n");
}
readData(data, parts, &inputSizes, &outputSizes, &compressedData, uncompressedSize);
if (ftruncate(outputFd, *uncompressedSize) == -1)
{
err(1, "Failed to set file size");
}
uncompressed = mmap(NULL, *uncompressedSize, PROT_READ | PROT_WRITE, MAP_SHARED, outputFd, 0);
if (uncompressed == MAP_FAILED || !uncompressed)
{
err(1, "Memory mapping failed: Unable to map %u bytes. Make sure you have enough memory available", *uncompressedSize);
}
DecompressThreadArgs args[parts];
for (uint32_t i = 0; i < parts; i++)
{
args[i].inputBuffer = compressedData + inputOffset;
args[i].outputBuffer = uncompressed + outputOffset;
args[i].srcSize = inputSizes[i];
args[i].dstSize = outputSizes[i];
args[i].id = i;
inputOffset += inputSizes[i];
outputOffset += outputSizes[i];View on GitHub (pinned to 742fc00b82)