{"record":{"id":"101987f35f710e2e","repo":"elastic/elasticsearch","slug":"assignprocesstojobobject","errorCode":null,"errorMessage":"AssignProcessToJobObject: {}","messagePattern":"AssignProcessToJobObject: (.+?)","errorType":"exception","errorClass":"UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"libs/native/src/main/java/org/elasticsearch/nativeaccess/WindowsNativeAccess.java","lineNumber":177,"sourceCode":"            throw new UnsupportedOperationException(\"CreateJobObject: \" + kernel.GetLastError());\n        }\n\n        try {\n            // retrieve the current basic limits of the job\n            int clazz = JOBOBJECT_BASIC_LIMIT_INFORMATION_CLASS;\n            var info = kernel.newJobObjectBasicLimitInformation();\n            if (kernel.QueryInformationJobObject(job, clazz, info) == false) {\n                throw new UnsupportedOperationException(\"QueryInformationJobObject: \" + kernel.GetLastError());\n            }\n            // modify the number of active processes to be 1 (exactly the one process we will add to the job).\n            info.setActiveProcessLimit(1);\n            info.setLimitFlags(JOB_OBJECT_LIMIT_ACTIVE_PROCESS);\n            if (kernel.SetInformationJobObject(job, clazz, info) == false) {\n                throw new UnsupportedOperationException(\"SetInformationJobObject: \" + kernel.GetLastError());\n            }\n            // assign ourselves to the job\n            if (kernel.AssignProcessToJobObject(job, kernel.GetCurrentProcess()) == false) {\n                throw new UnsupportedOperationException(\"AssignProcessToJobObject: \" + kernel.GetLastError());\n            }\n        } finally {\n            kernel.CloseHandle(job);\n        }\n\n        execSandboxState = ExecSandboxState.ALL_THREADS;\n        logger.debug(\"Windows ActiveProcessLimit initialization successful\");\n    }\n\n    @Override\n    public OptionalLong allocatedSizeInBytes(Path path) {\n        assert Files.isRegularFile(path) : path;\n        String fileName = \"\\\\\\\\?\\\\\" + path;\n        AtomicInteger lpFileSizeHigh = new AtomicInteger();\n\n        final int lpFileSizeLow = kernel.GetCompressedFileSizeW(fileName, lpFileSizeHigh::set);\n        if (lpFileSizeLow == INVALID_FILE_SIZE) {\n            logger.warn(\"Unable to get allocated size of file [{}]. Error code {}\", path, kernel.GetLastError());","sourceCodeStart":159,"sourceCodeEnd":195,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/native/src/main/java/org/elasticsearch/nativeaccess/WindowsNativeAccess.java#L159-L195","documentation":"Thrown as UnsupportedOperationException when kernel32.AssignProcessToJobObject() returns false. This is the final step of exec sandbox installation: assigning the current process to the job with ActiveProcessLimit=1. The failure includes GetLastError(). The most common cause is ERROR_ACCESS_DENIED when the process is already in another job that does not allow breakaway or nested assignment.","triggerScenarios":"Calling tryInstallExecSandbox() when the Elasticsearch process is already a member of a job object that prohibits assignment to a nested job. This is extremely common in containers (Docker on Windows), terminal services, and processes launched by service managers that use job objects.","commonSituations":"Running inside a Windows container (Docker, Hyper-V isolated pods). Process launched by a parent that placed it in a job without JOB_OBJECT_LIMIT_BREAKAWAY_OK. Running under Windows Terminal Services (session-based). SQL Server Agent or similar service hosts that use job objects. WSL2 processes.","solutions":["Decode GetLastError() (commonly 5 = ERROR_ACCESS_DENIED for nested job restriction).","If running in a container, this is expected; the exec sandbox cannot nest. Catch and continue.","If not in a container, check if a parent process (service host, launcher) placed the process in a job.","On Windows 8+, nested jobs are supported if the parent allows it; verify the parent job's limits."],"exampleFix":"// before\nwindowsNativeAccess.tryInstallExecSandbox();\n\n// after\ntry {\n    windowsNativeAccess.tryInstallExecSandbox();\n} catch (UnsupportedOperationException e) {\n    // common in containers and nested job environments\n    logger.warn(\"Could not assign process to Windows job object; exec sandbox not installed\", e);\n}","handlingStrategy":"try-catch","validationCode":"// Detect likely nested-job environments before attempting assignment.\nboolean likelyInJob = Boolean.getBoolean(\"es.container\")\n    || System.getenv(\"KUBERNETES_SERVICE_HOST\") != null;\nif (likelyInJob) {\n    logger.info(\"Running in a container; skipping Windows exec sandbox\");\n    return;\n}","typeGuard":null,"tryCatchPattern":"try {\n    nativeAccess.tryInstallExecSandbox();\n} catch (UnsupportedOperationException e) {\n    logger.warn(\"AssignProcessToJobObject failed (common in containers); exec sandbox not installed\", e);\n}","preventionTips":["In containerized Windows deployments, skip or catch the sandbox installation gracefully.","Understand that nested job assignment requires parent job cooperation.","Log the GetLastError() code for diagnosis."],"tags":["windows","native","security","sandbox","kernel32","job-object","container"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}