{"record":{"id":"3c8d628c905dfccb","repo":"elastic/elasticsearch","slug":"rlimit-nproc-unavailable","errorCode":null,"errorMessage":"RLIMIT_NPROC unavailable: {}","messagePattern":"RLIMIT_NPROC unavailable: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"warning","filePath":"libs/native/src/main/java/org/elasticsearch/nativeaccess/MacNativeAccess.java","lineNumber":154,"sourceCode":"                MemorySegment errorPtr = errorBuf.get(ValueLayout.ADDRESS, 0);\n                String message = MemorySegmentAdapter.getString(errorPtr.reinterpret(Long.MAX_VALUE), 0);\n                macLibc.sandbox_free_error(errorPtr);\n                throw new UnsupportedOperationException(\"sandbox_init(): \" + message);\n            }\n            logger.debug(\"OS X seatbelt initialization successful\");\n        } finally {\n            IOUtils.deleteFilesIgnoringExceptions(rules);\n        }\n    }\n\n    private void initBsdSandbox() {\n        RLimit limit = libc.newRLimit();\n        limit.rlim_cur(0);\n        limit.rlim_max(0);\n        // not a standard limit, means something different on linux, etc!\n        final int RLIMIT_NPROC = 7;\n        if (libc.setrlimit(RLIMIT_NPROC, limit) != 0) {\n            throw new UnsupportedOperationException(\"RLIMIT_NPROC unavailable: \" + libc.strerror(libc.errno()));\n        }\n\n        logger.debug(\"BSD RLIMIT_NPROC initialization successful\");\n    }\n}\n","sourceCodeStart":136,"sourceCodeEnd":160,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/native/src/main/java/org/elasticsearch/nativeaccess/MacNativeAccess.java#L136-L160","documentation":"Thrown during macOS BSD sandbox setup in tryInstallExecSandbox() → initBsdSandbox(). As a secondary hardening measure (beyond seatbelt), the code calls setrlimit(RLIMIT_NPROC=7, {0, 0}) to prevent the process from forking new processes. If setrlimit returns non-zero, this error fires with strerror. RLIMIT_NPROC=7 is macOS/BSD-specific (it means something different on Linux, hence the hardcoded constant).","triggerScenarios":"Calling tryInstallExecSandbox() on macOS where libc.setrlimit(RLIMIT_NPROC, limit) returns non-zero after setting both rlim_cur and rlim_max to 0. The limit struct was allocated via libc.newRLimit().","commonSituations":"Insufficient privileges to set resource limits; the process has already spawned child processes or threads that conflict with RLIMIT_NPROC=0; macOS versions where RLIMIT_NPROC semantics differ; running under an existing resource-limit policy that prevents lowering NPROC.","solutions":["Read the strerror in the message to identify the errno (commonly EPERM).","Ensure the ES process runs with sufficient privileges to call setrlimit.","Verify no child processes or excessive threads exist at the time of the call.","If the RLIMIT_NPROC hardening is not required, accept the failure — the seatbelt sandbox (error 669 path) is the primary defense."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    nativeAccess.tryInstallExecSandbox();\n} catch (UnsupportedOperationException e) {\n    // setrlimit(RLIMIT_NPROC, 0) failed.\n    logger.warn(\"BSD RLIMIT_NPROC sandbox unavailable: {}\", e.getMessage());\n}","preventionTips":["Ensure the ES process runs with privileges sufficient to call setrlimit.","Verify no existing resource-limit policy prevents lowering RLIMIT_NPROC.","Note that RLIMIT_NPROC is a secondary hardening measure — the seatbelt sandbox (initMacSandbox) is the primary defense."],"tags":["macos","bsd","security","native","rlimit","bootstrap"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}