{"record":{"id":"b53b2c7695322717","repo":"hashicorp/nomad","slug":"executor-shutdown-error-v-b53b2c","errorCode":null,"errorMessage":"executor shutdown error: %v","messagePattern":"executor shutdown error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"drivers/shared/executor/executor_windows.go","lineNumber":190,"sourceCode":"\tdefault:\n\t\treturn os.NewSyscallError(\"WaitForSingleObject\", err)\n\t}\n}\n\n// Send a Ctrl-Break signal for shutting down the process,\nfunc sendCtrlBreak(pid int) error {\n\terr := windows.GenerateConsoleCtrlEvent(syscall.CTRL_BREAK_EVENT, uint32(pid))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Error sending ctrl-break event: %v\", err)\n\t}\n\treturn nil\n}\n\n// Send the process a Ctrl-Break event, allowing it to shutdown by itself\n// before being Terminate.\nfunc (e *UniversalExecutor) shutdownProcess(_ os.Signal, proc *os.Process) error {\n\tif err := sendCtrlBreak(proc.Pid); err != nil {\n\t\treturn fmt.Errorf(\"executor shutdown error: %v\", err)\n\t}\n\te.logger.Debug(\"sent Ctrl-Break to process\", \"pid\", proc.Pid)\n\n\treturn nil\n}\n","sourceCodeStart":172,"sourceCodeEnd":196,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/drivers/shared/executor/executor_windows.go#L172-L196","documentation":"UniversalExecutor.shutdownProcess wraps any error from sendCtrlBreak with this message. It indicates the Windows executor failed to send the graceful Ctrl-Break shutdown event to the task process, so graceful shutdown was not performed.","triggerScenarios":"Calling UniversalExecutor.shutdownProcess (during task stop/kill) when windows.GenerateConsoleCtrlEvent fails — dead PID, missing console, or process not in a separate process group.","commonSituations":"Nomad stopping a Windows task whose process already exited or was started without proper console/process-group flags; shutdown timeouts cascading into kill paths.","solutions":["Inspect the wrapped cause (%v) — if it is 'process has already exited', the shutdown effectively succeeded and can be ignored","Ensure the driver launches processes with CREATE_NEW_PROCESS_GROUP so Ctrl-Break is routable","Rely on the subsequent TerminateProcess path to finish cleanup","Update Nomad to a version with the latest Windows executor signal fixes"],"exampleFix":"// before\nif err := sendCtrlBreak(proc.Pid); err != nil { return fmt.Errorf(\"executor shutdown error: %v\", err) }\n// after\nif err := sendCtrlBreak(proc.Pid); err != nil { return fmt.Errorf(\"executor shutdown error: %v\", err) }\n// caller: log and fall back to ForceStop/Kill on this error","handlingStrategy":"try-catch","validationCode":"if procAlreadyExited(pid) { return nil }","typeGuard":null,"tryCatchPattern":"err := executor.Shutdown(ctx)\nif err != nil && strings.Contains(err.Error(), \"executor shutdown error\") {\n    logger.Warn(\"graceful shutdown failed; forcing stop\", \"err\", err)\n    executor.Kill()\n}","preventionTips":["Always have a force-kill fallback after graceful shutdown errors","Log the wrapped cause to distinguish dead-PID from real failures","Keep Nomad updated for Windows signal handling fixes"],"tags":["windows","signal","shutdown"],"backgroundTag":"console-ctrl-event-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}