gofiber/fiber · critical

failed to listen

Error message

failed to listen: %w

What it means

Returned by App.Listen when app.createListener fails to bind the configured address. createListener wraps the underlying net.Listen / tls.Listen error as 'failed to listen', and Listen re-wraps it identically (listen.go:281/481), so the surfaced message is 'failed to listen: <net error>'. This is a socket-bind failure at server startup, before Serve runs.

Solutions

  1. Free the port: find and stop the holder (ss -ltnp / lsof -i :PORT) or pick a different port.
  2. For privileged ports, grant CAP_NET_BIND_SERVICE or run on :8080 behind a reverse proxy.
  3. For unix sockets, ensure the parent directory exists and is writable and set UnixSocketFileMode appropriately.
  4. Add SO_REUSEADDR via a custom listener / startup retry-with-backoff for the restart race, and fail fast with a clear log.

Example fix

// before
app.Listen(":80") // permission denied for non-root

// after
app.Listen(":8080") // or grant CAP_NET_BIND_SERVICE to the binary
Defensive patterns

Strategy: retry

Validate before calling

// preflight: is the address free before Listen?
ln, err := net.Listen("tcp", addr)
if err != nil {
    log.Fatalf("address %s unavailable: %v", addr, err)
}
_ = ln.Close()

Type guard

null

Try / catch

err := app.Listen(addr)
if err != nil {
    if strings.Contains(err.Error(), "failed to listen") {
        // bind failure: port taken, permission denied, bad addr
        log.Fatalf("cannot bind %s: %v", addr, err)
    }
    log.Fatal(err)
}

Prevention

When it happens

Trigger: Calling app.Listen(":3000") when the port is already taken; binding to a privileged port (<1024) as a non-root user; an invalid/malformed address; a unix socket path whose directory is not writable; or TLS Listen with a bad tls.Config.

Common situations: Another process (or a previous instance that did not release the port) holds the address; Docker host-network or port-publishing conflicts; binding to 0.0.0.0 when only loopback is permitted; unix-socket mode where /run/app dir is missing or has wrong perms; systemd unit restarting before the old socket closes.

Related errors


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/b0aee3579d52d271. Report an issue: GitHub.

Appendix: source

Thrown at listen.go:283

	}

	// Graceful shutdown
	if cfg.GracefulContext != nil {
		ctx, cancel := context.WithCancel(cfg.GracefulContext)
		defer cancel()

		go app.gracefulShutdown(ctx, &cfg)
	}

	// Start prefork
	if cfg.EnablePrefork {
		return app.prefork(addr, tlsConfig, &cfg)
	}

	// Configure Listener
	ln, err := app.createListener(addr, tlsConfig, &cfg)
	if err != nil {
		return fmt.Errorf("failed to listen: %w", err)
	}

	// Close the listener on any path that doesn't reach Serve (which otherwise
	// takes ownership of it) — an early error return or a panicking hook — so
	// the bound socket isn't leaked.
	served := false
	defer func() {
		if !served {
			_ = ln.Close() //nolint:errcheck // best-effort cleanup on the error path
		}
	}()

	// prepare the server for the start
	app.startupProcess()

	listenData := app.prepareListenData(ln.Addr().String(), getTLSConfig(ln) != nil, &cfg, nil)

	// run hooks

View on GitHub (pinned to a105acad6c)