Unrecovered panic in HTTP or RPC handler

A `panic` call appears inside an HTTP or RPC handler with no `recover()` in a deferred function, which can crash the goroutine or take down the server process.

panic-in-http-handler high confidence runtime go

Unrecovered panic in HTTP or RPC handler

What this failure means

A panic call appears inside an HTTP or RPC handler with no recover() in a deferred function, which can crash the goroutine or take down the server process.

Diagnosis

A panic call appears inside an HTTP or RPC handler function without a corresponding recover() in a deferred function.

In Go, an unrecovered panic propagates up the call stack and terminates the goroutine. For HTTP servers, each request runs in its own goroutine — an unrecovered panic in a handler leaves the client connection broken and may produce no log entry explaining why.

Common scenarios:

  • Explicit panic(...) used as a shortcut for “impossible” conditions that are reachable via external input
  • Unsafe type assertions (.(*T)) without the two-value form
  • Calling a third-party function that panics on bad input

Fix steps

  1. Add a recovery middleware at the router level so all handlers are protected: for Gin use r.Use(gin.Recovery()), for Echo use e.Use(middleware.Recover()), for stdlib net/http write a middleware that defers recover().
  2. Replace the explicit panic(...) with a returned error and an appropriate HTTP status code response.
  3. If intentional panics are used for “impossible” invariants, confirm they cannot be triggered by external input (user-supplied data should never reach a panic call).
  4. Use if err != nil { return ..., err } rather than panic(err) in all layers called by handlers.

Validation

  • go test ./…
  • go vet ./…

Why it matters

In Go, a panic that is not caught by a deferred recover() propagates up the call stack and terminates the goroutine. For HTTP servers, each request runs in its own goroutine — an unrecovered panic in a handler silently kills that goroutine, resulting in a broken connection for the client. Production frameworks provide recovery middleware precisely because this is a common mistake. The risk is highest when handler code calls third-party functions that may panic on invalid input.

Prevention

  • Apply a recovery middleware globally at the outermost router layer.
  • Lint for panic calls in non-test source files using go vet or a custom staticcheck rule.
  • Code review: flag any panic in a function reachable from an HTTP or gRPC handler.

Try it locally

make test
rg -n panic .
go test ./...
go vet ./...

How Faultline detects it

Use faultline explain panic-in-http-handler to see the full playbook.

faultline analyze build.log
faultline explain panic-in-http-handler

Generated from playbooks/bundled/source/panic-in-http-handler.yaml. Do not edit directly.

Try it on your own failed log

$ faultline analyze failed.log
Want this across every CI run? Faultline Teams tracks recurring failures across all your repos and surfaces patterns in a shared dashboard.