gofiber/fiber · critical

prefork: %w

Error message

prefork: %w

What it means

Fiber's prefork master (SO_REUSEPORT multi-process mode) failed to listen on addr: this wraps any error from fasthttp's prefork.ListenAndServe. Common causes: the address/port is already in use, binding a privileged port (<1024) without permission, SO_REUSEPORT unsupported on the platform/kernel, or a malformed address.

Source

Thrown at prefork.go:116

		}
		return nil
	}

	// Master callback: all children spawned → startup message & OnListen hooks
	p.OnMasterReady = func(childPIDs []int) error {
		listenData := app.prepareListenData(addr, tlsConfig != nil, cfg, childPIDs)
		app.runOnListenHooks(listenData)
		app.printMessages(cfg, listenData)
		return nil
	}

	// Master callback: child recovered after crash
	p.OnChildRecover = func(oldPID, newPID int) {
		logger.Printf("prefork: child %d crashed, recovered with new PID %d", oldPID, newPID)
	}

	if err := p.ListenAndServe(addr); err != nil {
		return fmt.Errorf("prefork: %w", err)
	}

	return nil
}

// dummyCmd is for internal prefork testing
func dummyCmd() *exec.Cmd {
	command := "go"
	if storeCommand := dummyChildCmd.Load(); storeCommand != nil && storeCommand != "" {
		command = storeCommand.(string) //nolint:forcetypeassert,errcheck // We always store a string in here
	}
	if runtime.GOOS == windowsOS {
		return exec.Command("cmd", "/C", command, "version")
	}
	return exec.Command(command, "version")
}

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Ensure the port is free (lsof/ss) and not held by another process or a previous instance.
  2. Confirm the OS supports SO_REUSEPORT (Linux >=3.9); disable EnablePrefork on unsupported platforms.
  3. Use a non-privileged port, or grant CAP_NET_BIND_SERVICE / run as root only if a privileged port is required.
  4. Verify the address string is well-formed (e.g. ':3000', '0.0.0.0:3000').

Example fix

// before
app.Listen(":80", fiber.ListenConfig{EnablePrefork: true})
// -> prefork: listen tcp :80: bind: address already in use

// after: free port + non-privileged, confirm REUSEPORT
app.Listen(":3000", fiber.ListenConfig{EnablePrefork: true})
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight: ensure the port is free before enabling prefork
func portFree(addr string) bool {
    ln, err := net.Listen("tcp", addr)
    if err != nil { return false }
    _ = ln.Close()
    return true
}

Try / catch

if err := app.Listen(addr, fiber.ListenConfig{EnablePrefork: true}); err != nil {
    log.Fatalf("prefork listen failed: %v", err)
}

Prevention

When it happens

Trigger: app.Listen(":80", fiber.ListenConfig{EnablePrefork: true}) when the port is taken, prefork/REUSEPORT is unsupported, or a privileged port is bound without privileges; or an invalid address string.

Common situations: Running two preforked instances on the same port; older kernels/containers without SO_REUSEPORT; binding <1024 as non-root; leftover process holding the port.

Related errors


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/abd0b523081de13a.json. Report an issue: GitHub.