Skip to content

go.channel_never_closed

Stability Medium

Detects channels that are created but never closed, causing goroutines waiting on them to leak.

Unclosed channels cause:

  • Goroutine leaks — Receivers block forever waiting
  • Memory leaks — Blocked goroutines hold references
  • Deadlocks — Range loops never terminate
  • Resource exhaustion — Slow accumulation of leaked goroutines
// ❌ Before (channel never closed)
func producer(ch chan int) {
for i := 0; i < 10; i++ {
ch <- i
}
// Channel never closed - consumers block forever!
}
func consumer(ch chan int) {
for v := range ch { // Blocks forever after producer done
process(v)
}
}
// ✅ After (channel closed)
func producer(ch chan int) {
defer close(ch)
for i := 0; i < 10; i++ {
ch <- i
}
}
func consumer(ch chan int) {
for v := range ch { // Terminates when channel closed
process(v)
}
}
  • make(chan T) without corresponding close()
  • Channels passed to functions without closing
  • Range loops over channels that are never closed

Unfault adds defer close(ch):

func produce(ch chan<- int) {
defer close(ch)
// ... produce values
}