{"record":{"id":"685c99d7446c6c37","repo":"go-delve/delve","slug":"could-not-attach-to-pid-d-s-685c99","errorCode":null,"errorMessage":"could not attach to pid %d: %s","messagePattern":"could not attach to pid (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/debugger/debugger_linux.go","lineNumber":19,"sourceCode":"package debugger\n\nimport (\n\t\"bufio\"\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n\t\"strings\"\n\t\"syscall\"\n)\n\nfunc init() {\n\tattachErrorMessage = attachErrorMessageLinux\n}\n\n//lint:file-ignore ST1005 errors here can be capitalized\n\nfunc attachErrorMessageLinux(pid int, err error) error {\n\tfallbackerr := fmt.Errorf(\"could not attach to pid %d: %s\", pid, err)\n\tif serr, ok := err.(syscall.Errno); ok {\n\t\tswitch serr {\n\t\tcase syscall.EPERM:\n\t\t\t// check if ptrace of non-child processes is disabled\n\t\t\tbs, err := os.ReadFile(\"/proc/sys/kernel/yama/ptrace_scope\")\n\t\t\tif err == nil && len(bs) >= 1 && bs[0] != '0' {\n\t\t\t\t// Yama documentation: https://www.kernel.org/doc/Documentation/security/Yama.txt\n\t\t\t\treturn fmt.Errorf(\"Could not attach to pid %d: this could be caused by a kernel security setting, try writing \\\"0\\\" to /proc/sys/kernel/yama/ptrace_scope\", pid)\n\t\t\t}\n\n\t\t\t// check if the pid belongs to a different process\n\t\t\tfi, err := os.Stat(fmt.Sprintf(\"/proc/%d\", pid))\n\t\t\tif err != nil {\n\t\t\t\treturn fallbackerr\n\t\t\t}\n\t\t\tif fi.Sys().(*syscall.Stat_t).Uid != uint32(os.Getuid()) {\n\t\t\t\treturn fmt.Errorf(\"Could not attach to pid %d: current user does not own the process\", pid)\n\t\t\t}","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/service/debugger/debugger_linux.go#L1-L37","documentation":"Generic fallback message produced by attachErrorMessageLinux in service/debugger/debugger_linux.go when 'dlv attach <pid>' fails with an error that is not a recognized syscall.Errno, or when none of the specific diagnostics (yama ptrace_scope, ownership, TracerPid) apply. It wraps the underlying ptrace/PTRACE_ATTACH error from the native backend.","triggerScenarios":"Calling debugger.Attach (or 'dlv attach <pid>') on Linux where the underlying ptrace attach returns an error other than EPERM, or EPERM whose cause is not yama ptrace_scope, wrong-owner, or already-traced.","commonSituations":"Attaching to a process that already exited between listing and attaching; attaching to a pid in another PID namespace or container; seccomp/LSM policies blocking ptrace; stale pid.","solutions":["Verify the pid exists and is alive: check /proc/<pid> before attaching","Retry attach as root or with CAP_SYS_PTRACE to rule out permission issues","Check the wrapped underlying error text for the real cause","Re-run in the same container/namespace as the target process"],"exampleFix":"// before\ndlv attach 12345\n// after\n# confirm target exists first\nkill -0 12345 && dlv attach 12345","handlingStrategy":"try-catch","validationCode":"if _, err := os.Stat(fmt.Sprintf(\"/proc/%d\", pid)); err != nil { return fmt.Errorf(\"pid %d not alive\", pid) }","typeGuard":"if errno, ok := err.(syscall.Errno); ok { /* handle EPERM/ESRCH specifically */ }","tryCatchPattern":"err := debugger.Attach(pid, []string{}, nil)\nif err != nil && strings.Contains(err.Error(), \"could not attach to pid\") {\n    // inspect wrapped cause, check /proc/<pid>, retry as root\n}","preventionTips":["Check /proc/<pid> existence before attaching","Run the debugger with sufficient privileges (root or CAP_SYS_PTRACE)","Attach within the same container/PID namespace as the target","Keep only one tracer per process"],"tags":["linux","ptrace","attach"],"backgroundTag":"ptrace-attach-failed","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}