elastic/elasticsearch · warning · UnsupportedOperationException
seccomp(SECCOMP_SET_MODE_FILTER): {}, prctl(PR_SET_SECCOMP):
Error message
seccomp(SECCOMP_SET_MODE_FILTER): {}, prctl(PR_SET_SECCOMP): {} What it means
Thrown during Linux seccomp sandbox setup in tryInstallExecSandbox(). This is the critical BPF filter installation step. The code first tries the modern seccomp(SECCOMP_SET_MODE_FILTER) syscall with the SECCOMP_FILTER_FLAG_TSYNC flag (applies to all threads). If that fails, it falls back to prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prog_address). If BOTH fail, this combined error is thrown with both strerror messages (errno1 from seccomp, errno2 from prctl). The 10-instruction BPF program blocks fork/vfork/execve/execveat.
Source
Thrown at libs/native/src/main/java/org/elasticsearch/nativeaccess/LinuxNativeAccess.java:319
/* 8 */ BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, arch.execveat, 1, 0), // if (syscall == EXECVEAT) goto fail;
/* 9 */ BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW), // pass: return OK;
/* 10 */ BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | (EACCES & SECCOMP_RET_DATA)), // fail: return EACCES;
};
// seccomp takes a long, so we pass it one explicitly to keep the JNA simple
SockFProg prog = linuxLibc.newSockFProg(insns);
int method = 1;
// install filter, if this works, after this there is no going back!
// first try it with seccomp(SECCOMP_SET_MODE_FILTER), falling back to prctl()
if (linuxLibc.syscall(arch.seccomp, SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, prog) != 0) {
method = 0;
int errno1 = libc.errno();
if (logger.isDebugEnabled()) {
logger.debug("seccomp(SECCOMP_SET_MODE_FILTER): {}, falling back to prctl(PR_SET_SECCOMP)...", libc.strerror(errno1));
}
if (linuxLibc.prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prog.segment().address(), 0, 0) != 0) {
int errno2 = libc.errno();
throw new UnsupportedOperationException(
"seccomp(SECCOMP_SET_MODE_FILTER): " + libc.strerror(errno1) + ", prctl(PR_SET_SECCOMP): " + libc.strerror(errno2)
);
}
}
// now check that the filter was really installed, we should be in filter mode.
if (linuxLibc.prctl(PR_GET_SECCOMP, 0, 0, 0, 0) != 2) {
throw new UnsupportedOperationException(
"seccomp filter installation did not really succeed. seccomp(PR_GET_SECCOMP): " + libc.strerror(libc.errno())
);
}
logger.debug("Linux seccomp filter installation successful, threads: [{}]", method == 1 ? "all" : "app");
execSandboxState = method == 1 ? ExecSandboxState.ALL_THREADS : ExecSandboxState.EXISTING_THREADS;
}
}
View on GitHub (pinned to db6a809a66)
Solutions
- Read both strerror values: errno1 (seccomp syscall) and errno2 (prctl fallback) — they often differ and pinpoint the issue.
- If errno1 is EPERM with TSYNC, the prctl fallback should work for the current thread — check why errno2 also fails.
- Check container runtime security policies: Docker seccomp profiles, Kubernetes PodSecurityPolicies/Admission policies.
- Verify os.arch matches a supported architecture in the ARCHITECTURES map (line 170) — an architecture mismatch means the BPF audit/limit/fork constants are wrong.
- Run dmesg | grep -i seccomp to check for kernel-level audit messages about the denied filter.
- If the sandbox is not required, accept the failure.
Defensive patterns
Strategy: try-catch
Try / catch
try {
nativeAccess.tryInstallExecSandbox();
} catch (UnsupportedOperationException e) {
// Both seccomp() syscall and prctl() fallback failed.
// The message contains BOTH strerror values for diagnosis.
logger.warn("BPF seccomp filter installation failed: {}", e.getMessage());
} Prevention
- Check container runtime seccomp profiles allow the seccomp() syscall and PR_SET_SECCOMP.
- For Docker, consider --security-opt seccomp=unconfined if the sandbox is not required, or use a profile that permits seccomp filter installation.
- Verify os.arch is in the ARCHITECTURES map — an unsupported architecture produces wrong BPF constants.
- Run dmesg | grep -i seccomp to find kernel-level denial messages.
- Ensure all threads in the process have compatible credentials for TSYNC (or accept the prctl single-thread fallback).
When it happens
Trigger: Calling tryInstallExecSandbox() where both linuxLibc.syscall(arch.seccomp, SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, prog) and the fallback linuxLibc.prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, prog.segment().address(), 0, 0) return non-zero. The debug log at line 314-315 shows the first failure and the fallback attempt.
Common situations: Container seccomp profiles that block the seccomp() syscall and PR_SET_SECCOMP; kernels where the BPF program is rejected (architecture mismatch, invalid instruction encoding); AppArmor/SELinux denying BPF filter installation; the TSYNC flag failing because threads have different credentials (EPERM) and the prctl fallback also blocked.
Related errors
- seccomp unavailable: requires kernel 3.5+ with CONFIG_SECCOM
- prctl(PR_GET_NO_NEW_PRIVS): {}
- seccomp unavailable: CONFIG_SECCOMP not compiled into kernel
- prctl(PR_GET_SECCOMP): {}
- seccomp unavailable: CONFIG_SECCOMP_FILTER not compiled into
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/8f788636a5e01b76.
Report an issue: GitHub.