go
concurrency_error
ai_generated
true
goroutine leak detected
ID: go/goroutine-leak
85%Fix Rate
88%Confidence
50Evidence
2023-01-01First Seen
Version Compatibility
| Version | Status | Introduced | Deprecated | Notes |
|---|---|---|---|---|
| 121 | active | — | — | — |
| 1 | active | — | — | — |
Root Cause
Goroutines are not being cleaned up, usually from missing context cancellation or blocked channel operations.
genericWorkarounds
-
92% success Add select with context.Done() to every goroutine for cancellation
go func(ctx context.Context) { for { select { case <-ctx.Done(): return case msg := <-ch: process(msg) } } }(ctx)Sources: https://pkg.go.dev/context
-
90% success Use errgroup for managing goroutine lifecycles
g, ctx := errgroup.WithContext(ctx) for _, item := range items { item := item g.Go(func() error { return process(ctx, item) }) } if err := g.Wait(); err != nil { log.Fatal(err) } -
85% success Monitor goroutine count with runtime.NumGoroutine() in tests
func TestNoLeak(t *testing.T) { before := runtime.NumGoroutine() doWork() time.Sleep(100 * time.Millisecond) after := runtime.NumGoroutine() if after > before+1 { t.Errorf("goroutine leak: before=%d after=%d", before, after) } }
Dead Ends
Common approaches that don't work:
-
Increase GOMAXPROCS to handle more goroutines
80% fail
GOMAXPROCS controls OS thread count, not goroutine count; leaked goroutines still consume memory
-
Use runtime.Goexit() to kill goroutines
85% fail
Goexit only terminates the calling goroutine; cannot kill other goroutines externally
Error Chain
Leads to:
Preceded by: