valyala/fasthttp · error

cannot enable so_reuseaddr: %w

Error message

cannot enable so_reuseaddr: %w

What it means

During fdSetup, setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 1) failed. The library always enables SO_REUSEADDR on listening sockets so the port can be rebound quickly after restart, and treats failure to do so as fatal, aborting NewListener.

Source

Thrown at tcplisten/tcplisten.go:95

	ln, err := net.FileListener(file)
	if err != nil {
		file.Close()
		return nil, err
	}

	if err = file.Close(); err != nil {
		ln.Close()
		return nil, err
	}

	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
		}

View on GitHub (pinned to c96f600972)

Solutions

  1. Read the wrapped errno: EBADF points to an earlier failure, ENOPROTOOPT to a missing option
  2. Relax container/seccomp policies to allow setsockopt(SOL_SOCKET, SO_REUSEADDR)
  3. Retry on a different OS/kernel that supports SO_REUSEADDR for the chosen family
  4. If unavoidable on the target platform, patch/vendor the library to tolerate SO_REUSEADDR failure

Example fix

// before
ln, err := cfg.NewListener("tcp", ":8080") // fails in seccomp sandbox
// after
// Docker: add --cap-add NET_ADMIN and/or adjust seccomp to allow setsockopt
// docker run --security-opt seccomp=unconfined ... (or a profile allowing setsockopt)
Defensive patterns

Strategy: validation

Validate before calling

// preflight: ensure setsockopt on a probe socket succeeds in this sandbox
s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, 0)
if err == nil {
    if serr := syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1); serr != nil {
        syscall.Close(s)
        log.Fatalf("sandbox blocks SO_REUSEADDR: %v", serr)
    }
    syscall.Close(s)
}

Type guard

null

Try / catch

ln, err := cfg.NewListener("tcp", addr)
if err != nil {
    if strings.Contains(err.Error(), "cannot enable so_reuseaddr") {
        var errno syscall.Errno
        if errors.As(err, &errno) {
            log.Printf("SO_REUSEADDR blocked (%v): adjust seccomp profile", errno)
        }
        return err
    }
}

Prevention

When it happens

Trigger: Calling NewListener where setsockopt(SO_REUSEADDR) returns an error: EBADF (invalid fd from earlier steps), ENOPROTOOPT (stack without the option), EPERM (restricted sandbox), or ENOMEM.

Common situations: Hardened seccomp/apparmor containers blocking setsockopt; exotic network stacks or OSes missing SO_REUSEADDR; fd corruption from a failed earlier setup step.

Related errors


AI-assisted analysis of valyala/fasthttp@c96f600972 (2026-08-31). Data as JSON: /api/errors/a8b32d60b9b2161e. Report an issue: GitHub.