TryBugHunt

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.

Go

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.

1. Inspect bounds & typesPrint or inspect collection sizes and verify variables are not empty or None/undefined.
2. Guard with safe accessUse optional chaining (?.), dictionary get(), or guard conditions before dereferencing.
3. Trace upstream originsFind where the value was instantiated or returned rather than only patching the symptom.

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 := <-ch

Works

ch := make(chan int, 1) // buffered channel of size 1
ch <- 42
val := <-ch

2. 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

medium

fatal 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))
}
Open with hintsRuns in your browser. No account needed.

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.

Related error guides