go-delve/delve · error

nil goroutine when attempting to switch to goroutine stack

Error message

nil goroutine when attempting to switch to goroutine stack

What it means

During stack unwinding, when the iterator crosses from the system stack (e.g. runtime code) back to the goroutine's own stack, it needs the goroutine descriptor (it.g) to restore PC/SP/BP. If it.g is nil the switch cannot be performed, so the iterator fails with this error. This is an internal invariant violation of the stack iterator.

Source

Thrown at pkg/proc/stack.go:346

			return true
		}
	}

	if it.frame.Ret <= 0 {
		it.atend = true
		return true
	}

	it.sigret = it.frame.Current.Fn != nil && it.frame.Current.Fn.Name == "runtime.sigpanic"
	it.top = false
	it.pc = it.frame.Ret
	it.regs = callFrameRegs
	return true
}

func (it *stackIterator) switchToGoroutineStack() error {
	if it.g == nil {
		return fmt.Errorf("nil goroutine when attempting to switch to goroutine stack")
	}
	it.systemstack = false
	it.top = false
	it.pc = it.g.PC
	it.regs.Reg(it.regs.SPRegNum).Uint64Val = it.g.SP
	it.regs.AddReg(it.regs.BPRegNum, op.DwarfRegisterFromUint64(it.g.BP))
	if it.bi.Arch.usesLR {
		lrReg := it.regs.Reg(it.regs.LRRegNum)
		if lrReg == nil {
			return fmt.Errorf("LR register is nil during stack switch")
		}
		lrReg.Uint64Val = it.g.LR
	}
	return nil
}

// Frame returns the frame the iterator is pointing at.
func (it *stackIterator) Frame() Stackframe {

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Ensure you evaluate stacks via a goroutine (GoroutineScope) rather than a raw thread when in runtime frames
  2. Re-read thread/goroutine state (Context, GetG) after the process resumes/stops again
  3. Update Delve; this is often an internal bug triggered by runtime version changes
  4. Check the target's Go runtime state isn't corrupted (e.g. from memory-write side effects)

Example fix

null
Defensive patterns

Strategy: type-guard

Validate before calling

if it.g == nil { return fmt.Errorf("cannot unwind: goroutine unknown; use GoroutineScope") }

Type guard

func canSwitchToGoroutineStack(it *stackIterator) bool { return it.g != nil }

Try / catch

err := iterateStack(g); if err != nil && strings.Contains(err.Error(), "nil goroutine") { /* fall back to thread-level stack or re-acquire g */ }

Prevention

When it happens

Trigger: Iterating a stack where a systemstack frame is encountered (systemstack==true) but the stackIterator was created without a valid *g pointer — e.g. unwinding a thread whose current goroutine could not be resolved, or corrupted goroutine state.

Common situations: Inspecting a thread stopped in runtime/scheduler code where goroutine association failed; debugging core dumps or partially-corrupted memory; stale goroutine pointer after process state changed unexpectedly.

Related errors


AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31). Data as JSON: /api/errors/90e08b6b813c8287. Report an issue: GitHub.