valyala/fasthttp · error
cannot enable so_reuseport: %w
Error message
cannot enable so_reuseport: %w
What it means
When the Config has ReusePort enabled, fdSetup sets SO_REUSEPORT (or SO_REUSEPORT_LB on FreeBSD/Darwin via soReusePort) and this setsockopt failed. ReusePort is opt-in, so this error only occurs when the user explicitly requested it and the platform/kernel cannot honor the option.
Source
Thrown at tcplisten/tcplisten.go:106
return ln, nil
}
func (cfg *Config) fdSetup(fd int, sa unix.Sockaddr, addr string) error {
var err error
if err = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_REUSEADDR, 1); err != nil {
return fmt.Errorf("cannot enable so_reuseaddr: %w", err)
}
// This should disable Nagle's algorithm in all accepted sockets by default.
// Users may enable it with net.TCPConn.SetNoDelay(false).
if err = unix.SetsockoptInt(fd, unix.IPPROTO_TCP, unix.TCP_NODELAY, 1); err != nil {
return fmt.Errorf("cannot disable nagle's algorithm: %w", err)
}
if cfg.ReusePort {
if err = unix.SetsockoptInt(fd, unix.SOL_SOCKET, soReusePort, 1); err != nil {
return fmt.Errorf("cannot enable so_reuseport: %w", err)
}
}
if cfg.DeferAccept {
if err = enableDeferAccept(fd); err != nil {
return err
}
}
if cfg.FastOpen {
if err = enableFastOpen(fd); err != nil {
return err
}
}
if err = unix.Bind(fd, sa); err != nil {
return fmt.Errorf("cannot bind to %q: %w", addr, err)
}View on GitHub (pinned to c96f600972)
Solutions
- Disable ReusePort (tcplisten.Config{ReusePort: false}) if the kernel does not support it
- Run Linux >= 3.9 (or FreeBSD with SO_REUSEPORT_LB >= FreeBSD 12) for SO_REUSEPORT support
- Check the wrapped errno; EPERM suggests sandbox restrictions, ENOPROTOOPT an unsupported option
- Gate ReusePort at startup with a runtime capability check before calling NewListener
Example fix
// before
cfg := tcplisten.Config{ReusePort: true}
ln, err := cfg.NewListener("tcp", ":8080") // fails on unsupported kernel
// after
cfg := tcplisten.Config{ReusePort: reusePortSupported()} // runtime-detected
ln, err := cfg.NewListener("tcp", ":8080") Defensive patterns
Strategy: fallback
Validate before calling
// runtime capability probe for SO_REUSEPORT
func reusePortSupported() bool {
s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, 0)
if err != nil { return false }
defer syscall.Close(s)
return syscall.SetsockoptInt(s, syscall.SOL_SOCKET, soReusePortConst, 1) == nil
} Type guard
null
Try / catch
cfg := tcplisten.Config{ReusePort: true}
ln, err := cfg.NewListener("tcp", addr)
if err != nil && strings.Contains(err.Error(), "cannot enable so_reuseport") {
cfg.ReusePort = false // graceful degradation
ln, err = cfg.NewListener("tcp", addr)
} Prevention
- Probe SO_REUSEPORT support at startup and degrade to ReusePort=false
- Require Linux >= 3.9 (or FreeBSD 12+ for SO_REUSEPORT_LB) in deployment docs
- Don't enable ReusePort on Windows/unsupported platforms
- Document kernel requirements alongside the zero-downtime restart setup
When it happens
Trigger: Calling tcplisten.Config{ReusePort: true}.NewListener(...) on platforms/kernels without SO_REUSEPORT support (older Linux <3.9 without the patch defining soReusePort appropriately, or Windows), or when setsockopt returns EPERM/EINVAL/ENOPROTOOPT.
Common situations: Enabling ReusePort on unsupported kernels or platforms (Windows, very old Linux); containers stripping the option; mismatched constant selection per GOOS; permission restrictions on the socket.
Related errors
- cannot enable so_reuseaddr: %w
- cannot make non-blocked listening socket: %w
- cannot create listening unblocked socket: %w
- cannot create listening socket: %w
- cannot mark listening socket close-on-exec: %w
AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31).
Data as JSON: /api/errors/8c95273ab445db2b.
Report an issue: GitHub.