fatal error: all goroutines are asleep - deadlock!
fatal error: all goroutines are asleep - deadlock! in Go means every running goroutine in your Go program is waiting on a channel or mutex lock, with no goroutine active to unlock or send data. The Go runtime detects this state and crashes immediately.
How do I fix fatal error: all goroutines are asleep - deadlock!?
To fix fatal error: all goroutines are asleep - deadlock! in Go, locate the line causing the error and check the values right before it runs. Most occurrences happen because of reading from an unbuffered channel without a separate sender goroutine. Apply a defensive check or safe fallback, make sure collections or objects exist before access, and verify return values from upstream functions.
What does fatal error: all goroutines are asleep - deadlock! mean?
Go's runtime contains a deadlock detector for the main goroutine and thread pool. If all goroutines are blocked waiting on operations (like reading from an unbuffered channel or acquiring a locked sync.Mutex), no progress is mathematically possible, causing an instant fatal crash.
Why does fatal error: all goroutines are asleep - deadlock! happen?
1. Reading from an unbuffered channel without a separate sender goroutine
Sending or receiving on an unbuffered channel blocks until the other side is ready. Doing both in the same goroutine causes an immediate deadlock.
Breaks
ch := make(chan int)
ch <- 42 // blocks forever waiting for a receiver!
val := <-chWorks
ch := make(chan int, 1) // buffered channel of size 1
ch <- 42
val := <-ch2. Calling sync.WaitGroup.Wait() before worker goroutines finish
If WaitGroup counter was incremented but worker goroutines never call wg.Done() (or wg.Wait() is called on the sender goroutine before closing the channel), Wait() blocks forever.
Breaks
var wg sync.WaitGroup
wg.Add(1)
// forgotten wg.Done() in goroutine!
wg.Wait()Works
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
// do work
}()
wg.Wait()How to find it in your own code
Ensure all channels have active senders and receivers running in separate goroutines, or buffer the channel appropriately. Always use defer wg.Done() when managing worker lifecycles with sync.WaitGroup. Close channels from the sender side when done producing values.
Try it: fix this bug
mediumfatal error: all goroutines are asleep - deadlock!
package main
import "fmt"
func drainTaskQueue(n int) []int {
ch := make(chan int, n)
for i := 1; i <= n; i++ {
ch <- i
}
var res []int
for val := range ch {
res = append(res, val)
}
return res
}
func main() {
fmt.Println(drainTaskQueue(3))
}More challenges with this error
Each of these challenges runs into this error or pattern. Find the bug and fix it in your browser — no install, no account needed.
Still not sure why yours breaks?
Paste it into the visualizer and watch it run line by line, with every variable at every step. Free, and it runs in your browser.