valyala/fasthttp · error

prefork: listen tcp %s: %w

Error message

prefork: listen tcp %s: %w

What it means

Returned by Prefork.setTCPListenerFiles when net.ListenTCP fails to bind the requested address/network. The library wraps the underlying error with the failing address so the developer knows exactly which address:port could not be bound during prefork listener setup. Prefork requires a bound listener that can be duplicated to child processes, so this failure aborts prefork startup.

Source

Thrown at prefork/prefork.go:314

		go p.watchMaster(os.Getppid())
	}

	return ln, nil
}

func (p *Prefork) setTCPListenerFiles(addr string) error {
	if p.Network == "" {
		p.Network = defaultNetwork
	}

	tcpAddr, err := net.ResolveTCPAddr(p.Network, addr)
	if err != nil {
		return fmt.Errorf("prefork: resolve %s/%s: %w", p.Network, addr, err)
	}

	tcpListener, err := net.ListenTCP(p.Network, tcpAddr)
	if err != nil {
		return fmt.Errorf("prefork: listen tcp %s: %w", addr, err)
	}

	listenerFile, err := tcpListenerFile(tcpListener)
	if err != nil {
		// Close the bound listener so we don't leak the socket/fd when
		// File() fails. p.ln is intentionally only assigned after this
		// point so the caller never sees a half-initialised state.
		_ = tcpListener.Close()
		return fmt.Errorf("prefork: dup listener fd: %w", err)
	}

	p.ln = tcpListener
	p.files = []*os.File{listenerFile}

	return nil
}

// childEnv returns os.Environ() with the prefork child marker variable set,

View on GitHub (pinned to c96f600972)

Solutions

  1. Free the port: stop or reconfigure the process already bound to the address (lsof -i :port / ss -ltnp).
  2. Use an unprivileged port or run with CAP_NET_BIND_SERVICE (setcap) if binding ports <1024.
  3. Verify the network type matches the address family (tcp4 vs tcp6) and the address string is valid.
  4. Check that the address resolves in the current environment (no bogus hostnames in config).

Example fix

// before
prefork: p.Listen(":80") without privileges
// after
p.Listen(":8080") or grant capability: sudo setcap 'cap_net_bind_service=+ep' /path/to/app
Defensive patterns

Strategy: validation

Validate before calling

// Before enabling prefork, check the address is bindable:
ln, err := net.Listen("tcp", addr)
if err != nil { log.Fatalf("cannot bind %s: %v", addr, err) }
ln.Close()

Try / catch

if err := p.Listen(addr); err != nil {
    var oe *net.OpError
    if errors.As(err, &oe) && errors.Is(oe.Err, syscall.EADDRINUSE) {
        log.Fatalf("port in use: %v", err)
    }
    log.Fatalf("prefork listen failed: %v", err)
}

Prevention

When it happens

Trigger: Calling prefork with an address that is already in use by another process, a privileged port (<1024) without root/CAP_NET_BIND_SERVICE, an invalid network type (e.g. tcp6 with an IPv4 address), or an unresolvable/invalid address string.

Common situations: Another instance of the app is still running and holding the port; running in a container without privileges binding to port 80/443; misconfigured LISTEN_ADDR environment variable; Docker port conflicts.

Related errors


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