argoproj/argo-workflows · error
failed to open remote thread in target process %d: %w
Error message
failed to open remote thread in target process %d: %w
What it means
After resolving CtrlRoutine, signalProcess injects a thread into the target process with createRemoteThread(hProc, ..., procCtrlRoutine.Addr(), signal, ...) to emulate a console signal (e.g. CTRL_BREAK) on Windows. If thread creation in the remote process fails, the signal could not be delivered and this wrapped error is returned.
Source
Thrown at workflow/executor/osspecific/signal_windows.go:81
// Code +/- copied from: https://github.com/microsoft/hcsshim/blob/1d69a9c658655b77dd4e5275bff99caad6b38416/internal/jobcontainers/process.go#L251
// License: MIT
// Author: Microsoft
func signalProcess(pid uint32, signal int) error {
hProc, err := windows.OpenProcess(windows.PROCESS_TERMINATE, true, pid)
if err != nil {
return fmt.Errorf("failed to open process: %w", err)
}
defer func() {
_ = windows.Close(hProc)
}()
if err := procCtrlRoutine.Find(); err != nil {
return fmt.Errorf("failed to load CtrlRoutine: %w", err)
}
threadHandle, err := createRemoteThread(hProc, nil, 0, procCtrlRoutine.Addr(), uintptr(signal), 0, nil)
if err != nil {
return fmt.Errorf("failed to open remote thread in target process %d: %w", pid, err)
}
defer func() {
_ = windows.Close(windows.Handle(threadHandle))
}()
return nil
}
// Following code has been generated using github.com/Microsoft/go-winio/tools/mkwinsyscall and inlined
// for easier usage
// HANDLE CreateRemoteThread(
//
// HANDLE hProcess,
// LPSECURITY_ATTRIBUTES lpThreadAttributes,
// SIZE_T dwStackSize,
// LPTHREAD_START_ROUTINE lpStartAddress,
// LPVOID lpParameter,
// DWORD dwCreationFlags,View on GitHub (pinned to 35bff19146)
Solutions
- Check the wrapped Windows error: ERROR_ACCESS_DENIED → privileges; ERROR_NOT_ENOUGH_MEMORY/quota → target resource limits
- If the process is already exiting, treat the signal failure as benign and verify completion via the exit-code file instead
- Run argoexec with sufficient token privileges for cross-process thread creation in job containers
- Fall back to TerminateProcess-style hard kill if graceful signaling is not required
Defensive patterns
Strategy: fallback
Validate before calling
// ensure handle allows thread creation
h, err := windows.OpenProcess(windows.PROCESS_TERMINATE|windows.PROCESS_CREATE_THREAD|windows.PROCESS_QUERY_INFORMATION, true, pid)
if err != nil { return err }
windows.Close(h) Try / catch
if err := osspecific.Kill(pid); err != nil && strings.Contains(err.Error(), "remote thread") {
// graceful signal failed; fall back to TerminateProcess or accept process-exiting race
} Prevention
- Treat signal-during-exit races as benign and verify completion via exit-code files
- Grant argoexec thread-creation rights in the container token
- Have a hard-kill fallback path for Windows signal delivery
When it happens
Trigger: Kill() → signalProcess() where createRemoteThread fails on a valid process handle — handle lacks THREAD_CREATE rights, the target process is exiting, or address space/quota restrictions apply.
Common situations: Target process terminating concurrently so remote thread creation is rejected; container/job-object security descriptors blocking thread injection; resource exhaustion (max threads/handles) in the target.
Related errors
- failed to open process: %w
- failed to load CtrlRoutine: %w
- cannot convert stdin to os.File, it was %T
- failed to read container args file %s: %w
- failed to unmarshal container args: %w
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/06d930a63d005621.
Report an issue: GitHub.