{"record":{"id":"b7d57d2bcbf2f2a1","repo":"go-delve/delve","slug":"could-not-attach-to-pid-d-current-user-does-not","errorCode":null,"errorMessage":"Could not attach to pid %d: current user does not own the process","messagePattern":"Could not attach to pid (.+?): current user does not own the process","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"service/debugger/debugger_linux.go","lineNumber":36,"sourceCode":"func 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}\n\n\t\t\t// check if the process is already being traced\n\t\t\tstatusfh, err := os.Open(fmt.Sprintf(\"/proc/%d/status\", pid))\n\t\t\tif err != nil {\n\t\t\t\treturn fallbackerr\n\t\t\t}\n\t\t\tdefer statusfh.Close()\n\t\t\tscan := bufio.NewScanner(statusfh)\n\t\t\tconst tracerPidPrefix = \"TracerPid:\"\n\t\t\tfor scan.Scan() {\n\t\t\t\tline := scan.Text()\n\t\t\t\tif strings.HasPrefix(line, tracerPidPrefix) {\n\t\t\t\t\ttpid, _ := strconv.Atoi(strings.TrimSpace(line[len(tracerPidPrefix):]))\n\t\t\t\t\tif tpid != 0 {\n\t\t\t\t\t\treturn fmt.Errorf(\"could not attach to pid %d: already being debugged by pid %d\", pid, tpid)\n\t\t\t\t\t}\n\t\t\t\t}","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/go-delve/delve/blob/a23773e6c31361e43246bc43a424ee009679b174/service/debugger/debugger_linux.go#L18-L54","documentation":"The target process exists but is owned by a different user (uid of /proc/<pid> differs from the current uid); ptrace refuses cross-user attach even with Yama disabled, so the debugger reports the ownership mismatch explicitly.","triggerScenarios":"'dlv attach <pid>' where os.Stat(\"/proc/<pid>\") succeeds but the stat Uid differs from os.Getuid(), while EPERM was returned.","commonSituations":"Attaching to a service running as www-data/systemd user; attaching inside Docker to a process started as root from a non-root shell; shared dev servers.","solutions":["Run dlv attach as root (sudo dlv attach <pid>)","Run the target process under your own user account","Attach from inside the container with matching user credentials","Use dlv exec to launch the program under the debugger instead of attaching"],"exampleFix":"// before\ndlv attach 12345 // process owned by www-data\n// after\nsudo dlv attach 12345","handlingStrategy":"validation","validationCode":"fi, err := os.Stat(fmt.Sprintf(\"/proc/%d\", pid))\nif err == nil {\n    owned := fi.Sys().(*syscall.Stat_t).Uid == uint32(os.Getuid())\n}","typeGuard":"if st, ok := fi.Sys().(*syscall.Stat_t); ok && st.Uid != uint32(os.Getuid()) { /* not owner */ }","tryCatchPattern":"err := debugger.Attach(pid, []string{}, nil)\nif err != nil && strings.Contains(err.Error(), \"does not own the process\") {\n    // re-exec attach with sudo or under the owning user\n}","preventionTips":["Verify the target uid matches the debugger uid before attaching","Run delve under the same user that started the program","Use sudo or setuid wrapper when attaching to system services","In containers, exec into the container with a matching uid"],"tags":["linux","permissions","ptrace","uid"],"backgroundTag":"process-ownership-mismatch","analyzedSha":"a23773e6c31361e43246bc43a424ee009679b174","analyzedAt":"2026-08-31T15:12:45.221Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}