valyala/fasthttp · error
prefork: exceeding the value of recoverthreshold
Error message
prefork: exceeding the value of recoverthreshold
What it means
In prefork mode, the parent supervises child processes; if a child keeps dying and the number of restarts exceeds RecoverThreshold, prefork gives up and returns ErrOverRecovery to avoid an infinite crash-restart loop.
Source
Thrown at prefork/prefork.go:48
// masterPollInterval is the period of the watchMaster ppid-poll on Unix.
masterPollInterval = 500 * time.Millisecond
// defaultShutdownGracePeriod is how long the master waits for children to
// exit cleanly after sending SIGTERM before forcibly killing them.
defaultShutdownGracePeriod = 5 * time.Second
)
var (
defaultLogger = Logger(log.New(os.Stderr, "", log.LstdFlags))
// tcpListenerFile is a hook for (*net.TCPListener).File so tests can
// inject failure paths without binding a real socket.
tcpListenerFile = (*net.TCPListener).File
// ErrOverRecovery is returned when child prefork process restarts exceed
// the value of RecoverThreshold.
ErrOverRecovery = errors.New("prefork: exceeding the value of recoverthreshold")
// ErrOnlyReuseportOnWindows is returned when running on Windows without Reuseport.
ErrOnlyReuseportOnWindows = errors.New("prefork: windows only supports reuseport = true")
// ErrCommandProducerNilCmd is returned when a CommandProducer returns
// (nil, nil) instead of a started command.
ErrCommandProducerNilCmd = errors.New("prefork: commandproducer returned nil command")
// ErrCommandProducerNotStarted is returned when a CommandProducer returns
// an *exec.Cmd whose Process is nil (i.e. cmd.Start() was not called).
ErrCommandProducerNotStarted = errors.New("prefork: commandproducer must return a started command")
)
// Logger is used for logging formatted messages. Its method set is intentionally
// identical to fasthttp.Logger so that *fasthttp.Server.Logger can be assigned
// directly.
type Logger interface {
// Printf must have the same semantics as log.Printf.View on GitHub (pinned to c96f600972)
Solutions
- Fix the underlying child crash first: check logs — typically port conflicts (SO_REUSEPORT/port in use) or panics during app setup.
- Raise prefork.Options.RecoverThreshold (and/or RecoverInterval) if restarts are expected to be transient.
- Verify Reuseport settings and that the listening address is free before enabling prefork.
Example fix
// before
pf := prefork.New(app) // default RecoverThreshold
err := pf.Listen(":8080") // children crash-loop -> ErrOverRecovery
// after
pf := prefork.New(app)
pf.RecoverThreshold = 10
// and fix the child crash (e.g. free port :8080)
err := pf.Listen(":8080") Defensive patterns
Strategy: try-catch
Try / catch
err := pf.Listen(":8080")
if errors.Is(err, prefork.ErrOverRecovery) {
log.Fatal("children keep crashing past RecoverThreshold; check port conflicts and startup panics")
} Prevention
- Smoke-test the app in non-prefork mode first so child crashes surface clearly.
- Ensure the port is free and Reuseport is configured correctly.
- Set RecoverThreshold/RecoverInterval appropriate to your environment.
When it happens
Trigger: Running prefork.Listen/Run where a child process repeatedly crashes on startup (bind failure, fatal handler error) more times than RecoverThreshold within the recovery window.
Common situations: Port already in use causing every child to fail binding; a panic during app initialization (bad config, missing env); setting RecoverThreshold too low for legitimately flaky environments.
Related errors
- prefork: windows only supports reuseport = true
- prefork: commandproducer returned nil command
- prefork: commandproducer must return a started command
- prefork: close inherited listener fd: %w
- prefork: resolve %s/%s: %w
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/33eab4d63bd46196.
Report an issue: GitHub.