go-delve/delve · error
could not attach to %d
Error message
could not attach to %d
What it means
On macOS, attaching requires acquiring the target's mach task port via acquire_mach_task. If the mach call does not return KERN_SUCCESS, Delve cannot control the process and Attach fails with "could not attach to <pid>". This is the mach-level equivalent of a ptrace attach denial.
Source
Thrown at pkg/proc/native/proc_darwin.go:161
return 0, proc.ErrWaitForNotImplemented
}
// Attach to an existing process with the given PID.
func Attach(pid int, waitFor *proc.WaitFor, _ []string) (*proc.TargetGroup, error) {
if waitFor.Valid() {
return nil, proc.ErrWaitForNotImplemented
}
if err := macutil.CheckRosetta(); err != nil {
return nil, err
}
dbp := newProcess(pid)
kret := C.acquire_mach_task(C.int(pid),
&dbp.os.task, &dbp.os.portSet, &dbp.os.exceptionPort,
&dbp.os.notificationPort)
if kret != C.KERN_SUCCESS {
return nil, fmt.Errorf("could not attach to %d", pid)
}
dbp.os.initialized = true
var err error
dbp.execPtraceFunc(func() { err = ptraceAttach(dbp.pid) })
if err != nil {
return nil, err
}
_, _, err = dbp.wait(dbp.pid, 0)
if err != nil {
return nil, err
}
tgt, err := dbp.initialize("", []string{})
if err != nil {
detachWithoutGroup(dbp, false)
return nil, errView on GitHub (pinned to a23773e6c3)
Solutions
- Confirm the pid is correct and the process is still alive (ps -p <pid>).
- Ensure you own the target process; run dlv with sudo only if necessary.
- Enable developer mode (`sudo DevToolsSecurity -enable`) and make sure dlv is properly signed.
- Check the target isn't already debugged by another debugger (lldb, another dlv).
- Avoid attaching to SIP-protected system processes; re-launch a non-protected copy instead.
Example fix
// before dlv attach 9999 // pid guessed, already dead // after ps aux | grep myapp dlv attach $(pgrep -u $USER myapp)
Defensive patterns
Strategy: validation
Validate before calling
p, err := os.FindProcess(pid)
if err != nil {
return err
}
if err := p.Signal(syscall.Signal(0)); err != nil {
return fmt.Errorf("pid %d not attachable/alive: %w", pid, err)
}
// also ensure process owner matches current user (ps -o user -p pid) Try / catch
tgt, err := proc.Attach(pid, [], logger)
if err != nil && strings.Contains(err.Error(), "could not attach to") {
// check pid, ownership, SIP, and existing debugger before retrying
} Prevention
- Resolve the pid immediately before attaching to avoid exit races.
- Only attach to processes you own; escalate deliberately if needed.
- Enable developer mode and keep delve properly codesigned on macOS.
- Never attach to SIP-protected system binaries.
When it happens
Trigger: Calling `dlv attach <pid>` (proc.Attach) on macOS when acquire_mach_task returns non-KERN_SUCCESS: wrong pid, process owned by another user, target already being debugged, or SIP protection.
Common situations: Attaching to a process started by another user or by launchd; attaching to a pid that already exited (race between finding the pid and attaching); attaching to system binaries protected by SIP; missing developer mode / codesign entitlements on the delve binary.
Related errors
- could not get registers
- could not resume task
- error while waiting for task
- could not follow task across exec: %d
- error waiting for thread stop %d
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/95375c08e25923ce.
Report an issue: GitHub.