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
- Add a recovery middleware at the router level so all handlers are protected: for Gin use
r.Use(gin.Recovery()), for Echo usee.Use(middleware.Recover()), for stdlibnet/httpwrite a middleware that defersrecover(). - Replace the explicit
panic(...)with a returned error and an appropriate HTTP status code response. - If intentional panics are used for “impossible” invariants, confirm they cannot be triggered by external input (user-supplied data should never reach a
paniccall). - Use
if err != nil { return ..., err }rather thanpanic(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
paniccalls in non-test source files usinggo vetor a custom staticcheck rule. - Code review: flag any
panicin 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.