Select With No Cases Blocks Forever

fatal error: all goroutines are asleep - deadlock! (caused by empty select)

Quick Answer

An empty select{} blocks the goroutine forever. Use it only in main to keep the program alive, and ensure other goroutines can make progress.

Why This Happens

select{} with no cases blocks the current goroutine permanently. This is sometimes used intentionally in main to keep a server running, but if used accidentally or if all other goroutines also block, it causes a deadlock.

The Problem

func main() {
    select {} // blocks forever, no other goroutines running
}

The Fix

func main() {
    srv := &http.Server{Addr: ":8080"}
    go func() {
        if err := srv.ListenAndServe(); err != nil {
            log.Fatal(err)
        }
    }()
    // Block main goroutine while server runs
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, os.Interrupt)
    <-quit
    srv.Shutdown(context.Background())
}

Step-by-Step Fix

  1. 1

    Identify the empty select

    Find select{} statements that may cause unintended blocking.

  2. 2

    Add exit conditions

    Add a case for a quit channel, signal, or context cancellation.

  3. 3

    Use proper shutdown

    Implement graceful shutdown with os/signal and context for production services.

Bugsly catches this automatically

Bugsly's AI analyzes this error pattern in real-time, explains what went wrong in plain English, and suggests the exact fix — before your users even report it.

Try Bugsly free