Skip to content

/errors/go/all-goroutines-are-asleep-deadlock

Go fatal error: all goroutines are asleep - deadlock!

The commands on this page have not been executed by our verification runner yet.updated
tool
Go
exit code
2
versions
Go 1.x
os
any

fatal error: all goroutines are asleep - deadlock! means every goroutine in the program is blocked, waiting on a channel operation, a WaitGroup or a lock that nothing can ever release, so the Go runtime stops the program. The classic case is sending on an unbuffered channel from main with no goroutine receiving. Start the other side in a goroutine, use a buffered channel, or close the channel when sending is done.

Example

main.go
package main

import "fmt"

func main() {
	ch := make(chan int) // unbuffered: a send waits for a receiver
	ch <- 1              // no other goroutine exists to receive
	fmt.Println(<-ch)
}

The program prints the message followed by a dump of the blocked goroutines and exits with status 2:

text
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()

Fixes

go
// 1. Receive in another goroutine (or send from one)
ch := make(chan int)
go func() { ch <- 1 }()
fmt.Println(<-ch)

// 2. Buffered channel: the send does not wait while there is room
buf := make(chan int, 1)
buf <- 1
fmt.Println(<-buf)

// 3. Close the channel so range stops
jobs := make(chan int)
go func() {
	defer close(jobs)
	for i := 0; i < 3; i++ {
		jobs <- i
	}
}()
for j := range jobs {
	fmt.Println(j)
}

Reading the goroutine states

State in the dumpBlocked on
[chan send]A send with no receiver (or a full buffered channel)
[chan receive]A receive with no sender and no close
[select (no cases)]An empty select {} with nothing else running
[semacquire] / [sync.WaitGroup.Wait]WaitGroup.Wait or Mutex.Lock that is never released

Sources