go-delve/delve · error

negative maximum stack depth

Error message

negative maximum stack depth

What it means

stacktrace validates the requested maximum depth and rejects negative values before walking the stack. Callers pass the user-specified depth limit for stack unwinding; a negative number is meaningless and signals a caller bug.

Source

Thrown at pkg/proc/stack.go:438

	if fn != nil && !fn.cu.image.Stripped() && !r.SystemStack && it.g != nil {
		dwarfTree, _ := fn.cu.image.getDwarfTree(fn.offset)
		if dwarfTree != nil {
			c := readLocalPtrVar(dwarfTree, goClosurePtr, it.target, it.bi, fn.cu.image, r.Regs, it.mem)
			if c != 0 {
				if c >= it.g.stack.lo && c < it.g.stack.hi {
					r.closurePtr = int64(c) - int64(it.g.stack.hi)
				} else {
					r.closurePtr = int64(c)
				}
			}
		}
	}
	return r
}

func (it *stackIterator) stacktrace(depth int, initialFrames []Stackframe) ([]Stackframe, error) {
	if depth < 0 {
		return nil, errors.New("negative maximum stack depth")
	}
	var frames []Stackframe
	if len(initialFrames) > 0 {
		frames = initialFrames
		if len(frames) >= depth+1 {
			return frames, nil
		}
	} else {
		frames = make([]Stackframe, 0, depth+1)
	}
	f := func(frame Stackframe) bool {
		frames = append(frames, frame)
		return len(frames) < depth+1
	}
	it.stacktraceFunc(f)
	if it.Err() != nil && len(frames) == 1 && it.g != nil && frames[0].SystemStack && (it.opts&StacktraceSimple == 0) {
		// If we can't continue from the first frame, and it was on a system stack
		// and we have a goroutine which we are allowed to switch to then switch

View on GitHub (pinned to a23773e6c3)

Solutions

  1. Pass a non-negative depth, or a large sentinel (e.g. math.MaxInt32) for 'unlimited'
  2. Validate user/config-supplied depth values before calling the API
  3. Clamp depth: if depth < 0 { depth = defaultDepth }

Example fix

// before
frames, err := g.Stack(-1, false)
// after
depth := requestedDepth
if depth < 0 { depth = 50 }
frames, err := g.Stack(depth, false)
Defensive patterns

Strategy: validation

Validate before calling

func sanitizeDepth(d int) int {
    if d < 0 {
        return defaultMaxStackDepth // e.g. 50
    }
    return d
}

Try / catch

frames, err := g.Stack(depth, false)
if err != nil && strings.Contains(err.Error(), "negative maximum stack depth") {
    return fmt.Errorf("invalid depth %d: must be >= 0", depth)
}

Prevention

When it happens

Trigger: Calling any stack-unwinding API (e.g. Thread/ Goroutine stack requests, depth-parameterized Stack functions) with depth < 0.

Common situations: RPC clients computing depth from arithmetic that underflowed (e.g. subtracting from 0); CLI/config parsing that produced -1 as a sentinel; copying example code with placeholder negatives.

Related errors


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