Skip to content

Critical: Graceful shutdown logic is unreachable #32

@sgaunet

Description

@sgaunet

Description

The graceful shutdown code at lines 274-278 is unreachable, meaning the server never shuts down gracefully and active connections are terminated abruptly on SIGTERM/SIGINT.

Location

http-echo.go:270-278

if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
    log.Fatalf("Could not start server: %s\n", err.Error())
}

// Lines 274-278 are unreachable
ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
    log.Printf("Server shutdown error: %s\n", err.Error())
}

Impact

  • Severity: HIGH
  • Active HTTP requests are terminated immediately
  • No graceful connection draining
  • Poor experience in container/Kubernetes environments
  • Shutdown timeout configuration is unused

Root Cause

ListenAndServe() blocks until the server stops. Any error that isn't http.ErrServerClosed causes log.Fatalf() to exit the program, making lines 274-278 unreachable.

Recommended Fix

Implement proper signal handling with goroutines:

func main() {
    var h helloWorldhandler
    server := &http.Server{
        Addr:           ":8080",
        Handler:        h,
        ReadTimeout:    readTimeout,
        WriteTimeout:   writeTimeout,
        IdleTimeout:    idleTimeout,
        MaxHeaderBytes: maxHeaderBytes,
    }

    // Start server in goroutine
    go func() {
        log.Println("Starting server on :8080")
        if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
            log.Fatalf("Could not start server: %s\n", err.Error())
        }
    }()

    // Wait for interrupt signal
    quit := make(chan os.Signal, 1)
    signal.Notify(quit, os.Interrupt, syscall.SIGTERM)
    <-quit

    log.Println("Shutdown signal received, shutting down gracefully...")
    ctx, cancel := context.WithTimeout(context.Background(), shutdownTimeout)
    defer cancel()
    if err := server.Shutdown(ctx); err != nil {
        log.Printf("Server shutdown error: %s\n", err.Error())
    }
    log.Println("Server stopped")
}

Note: Add "os/signal" and "syscall" to imports.

Testing

  • Start the server and send SIGTERM: kill -TERM <pid>
  • Verify graceful shutdown message appears
  • Confirm active requests complete before shutdown
  • Test in Docker/Kubernetes with terminationGracePeriodSeconds

Priority

Critical - Essential for production deployments, especially in containerized environments.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions