{"record":{"id":"d7ef57de3e97c12c","repo":"openjdk/jdk","slug":"waitforsingleobject-failed-lu","errorCode":null,"errorMessage":"WaitForSingleObject failed: %lu\n","messagePattern":"WaitForSingleObject failed: %lu\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/java.base/windows/native/launcher/relauncher.c","lineNumber":233,"sourceCode":"        fprintf(stderr, \"%s: executing: '%s' '%s'\\n\", program_name, java_path, command_line);\n    }\n\n    STARTUPINFO si;\n    PROCESS_INFORMATION pi;\n\n    memset(&si, 0, sizeof(si));\n    si.cb = sizeof(si);\n    memset(&pi, 0, sizeof(pi));\n\n    // Windows has no equivalent of exec, so start the process and wait for it\n    // to finish, to be able to return the same exit code\n    if (!CreateProcess(java_path, command_line, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {\n        fprintf(stderr, \"CreateProcess failed: %lu\\n\", GetLastError());\n        return 1;\n    }\n\n    if (WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_FAILED) {\n        fprintf(stderr, \"WaitForSingleObject failed: %lu\\n\", GetLastError());\n        return 1;\n    }\n\n    DWORD exit_code;\n    if (!GetExitCodeProcess(pi.hProcess, &exit_code)) {\n        fprintf(stderr, \"GetExitCodeProcess failed: %lu\\n\", GetLastError());\n        return 1;\n    }\n    CloseHandle(pi.hProcess);\n    CloseHandle(pi.hThread);\n\n    return exit_code;\n}\n","sourceCodeStart":215,"sourceCodeEnd":247,"githubUrl":"https://github.com/openjdk/jdk/blob/88dfb74bbeefcf2b0aa11835183bcd949998fc8f/src/java.base/windows/native/launcher/relauncher.c#L215-L247","documentation":"Windows launcher relauncher: java.exe was successfully spawned, but WaitForSingleObject(pi.hProcess, INFINITE) returned WAIT_FAILED, so the relauncher cannot obtain the child's exit code and exits with 1 instead of propagating java's status. The message prints GetLastError(). Common underlying errors are invalid/garbage process handles or waiting being interrupted in unusual ways.","triggerScenarios":"The process handle became invalid between CreateProcess and the wait — e.g. the handle table was manipulated, a job-object or sandbox policy closed foreign handles, or hooking/injection software interfered with the wait. On stock Windows an INFINITE wait on a fresh process handle essentially cannot fail.","commonSituations":"Running java under job objects with kill-on-close semantics (CI runners tearing down jobs), sandboxing/anti-cheat-style DLL injection, or debugging tools that suspend/redirect child processes.","solutions":["Look up the GetLastError() code printed by the message for the exact failure (e.g. ERROR_INVALID_HANDLE = 6, WAIT timeout-related codes)","Run outside sandboxing/hooking environments (job objects that close handles, injection frameworks) to isolate the interference","Run bin\\java.exe directly instead of through the relauncher to confirm the JVM itself is healthy","If it happens in CI, ensure the agent does not kill/close child handles while the build step waits"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Avoid launch wrappers that close or steal child process handles (job objects with kill-on-close, DLL injectors)","When a supervisor must manage java, have it open/keep its own duplicated handle to the child"],"tags":["jdk","launcher","windows","process-wait","environment"],"backgroundTag":null,"analyzedSha":"88dfb74bbeefcf2b0aa11835183bcd949998fc8f","analyzedAt":"2026-08-14T11:45:09.665Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}