{"record":{"id":"ffe9d6a330ced427","repo":"go-delve/delve","slug":"waiting-for-target-execve-failed-s-ffe9d6","errorCode":null,"errorMessage":"waiting for target execve failed: %s","messagePattern":"waiting for target execve failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/proc/native/proc_linux.go","lineNumber":132,"sourceCode":"\t\t\tdbp.ctty, err = attachProcessToTTY(process, tty)\n\t\t\tif err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif wd != \"\" {\n\t\t\tprocess.Dir = wd\n\t\t}\n\t\terr = process.Start()\n\t})\n\tclosefn()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdbp.pid = process.Process.Pid\n\tdbp.childProcess = true\n\t_, _, err = dbp.wait(process.Process.Pid, 0)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"waiting for target execve failed: %s\", err)\n\t}\n\ttgt, err := dbp.initialize(cmd[0], debugInfoDirs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tsetupSharedLibBreakpoint(dbp, tgt)\n\treturn tgt, nil\n}\n\n// Attach to an existing process with the given PID. Once attached, if\n// the DWARF information cannot be found in the binary, Delve will look\n// for external debug files in the directories passed in.\nfunc Attach(pid int, waitFor *proc.WaitFor, debugInfoDirs []string) (*proc.TargetGroup, error) {\n\tif waitFor.Valid() {\n\t\tvar err error\n\t\tpid, err = WaitFor(waitFor)\n\t\tif err != nil {\n\t\t\treturn nil, err","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/pkg/proc/native/proc_linux.go#L114-L150","documentation":"During nativeProcess.Launch on Linux, delve forks/execs the target and waits for the child to stop at its first execve (PTRACE_TRACEME + exec). If dbp.wait returns an error while waiting for that execve stop, delve wraps it as 'waiting for target execve failed'. Launch cannot proceed because the child never reached a traceable state.","triggerScenarios":"Calling debugger.Launch (dlv debug/exec) when the exec'd wait fails: the child crashed instantly after fork (e.g. exec binary missing despite pre-checks), was killed by a signal, or wait returned EINTR/ECHILD.","commonSituations":"Launching a binary that immediately segfaults; target binary with a bad interpreter shebang; exec'ing setuid binaries that drop traceability; seccomp/LSM policies (Yama ptrace_scope=2/3) blocking the child; disk/exec failures under sandboxed CI.","solutions":["Run the target binary manually to confirm it starts: ./your-binary --help.","Check kernel.yama.ptrace_scope (set to 0 or 1) and run delve as the same user or root.","Retry the launch; single EINTR during wait is often transient.","If the binary is setuid/setgid, remove those bits or launch via a non-setuid copy; ptrace of privileged children is blocked.","Verify the command array's first element is a valid executable path."],"exampleFix":"// before\ncmd := []string{\"./app\", \"--flag\"} // app is setuid, launch fails\n\n// after\n// chmod u-s ./app  (remove setuid so ptrace is permitted)\ncmd := []string{\"/abs/path/app\", \"--flag\"}\n_ = debugger.Launch(cmd, \"\", false)","handlingStrategy":"validation","validationCode":"// validate target and ptrace environment before Launch on Linux\nfunc preflightLaunch(bin string) error {\n    if fi, err := os.Stat(bin); err != nil || fi.IsDir() {\n        return fmt.Errorf(\"binary %s not executable\", bin)\n    }\n    if fi, _ := os.Stat(bin); fi.Mode()&(os.ModeSetuid|os.ModeSetgid) != 0 {\n        return fmt.Errorf(\"remove setuid/setgid bits; ptrace of privileged children is blocked\")\n    }\n    yama, _ := os.ReadFile(\"/proc/sys/kernel/yama/ptrace_scope\")\n    if s := strings.TrimSpace(string(yama)); s == \"2\" || s == \"3\" {\n        return fmt.Errorf(\"kernel.yama.ptrace_scope=%s blocks launch; set to 0 or 1\", s)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"tgt, err := debugger.Launch(cmd, \"\", false)\nif err != nil && strings.Contains(err.Error(), \"waiting for target execve failed\") {\n    // child died before/at execve: run it standalone to see the real failure\n    return fmt.Errorf(\"%w (run %q manually to see the exec error)\", err, cmd[0])\n}","preventionTips":["Run the binary standalone first to confirm it execs cleanly.","Remove setuid/setgid bits from the target.","Set kernel.yama.ptrace_scope to 0 or 1, or run as root.","Use absolute executable paths in the launch command.","Retry once — transient EINTR during the post-fork wait is common."],"tags":["linux","ptrace","exec","process-launch"],"backgroundTag":"execve-wait-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}