nsqio/nsq · critical

listen (%s) failed - %s

Error message

listen (%s) failed - %s

What it means

nsqd failed to bind its TCP listener (net.Listen on opts.TCPAddress, default 0.0.0.0:4150, flag --tcp-address). This is the NSQ protocol V2 socket that producers and consumers connect to. New() wraps the underlying net.Listen error (address in use, permission denied, invalid address, DNS failure) with the requested address, so the cause is visible after the dash.

Source

Thrown at nsqd/nsqd.go:154

	n.clientTLSConfig = clientTLSConfig

	if opts.AuthHTTPRequestMethod != "post" && opts.AuthHTTPRequestMethod != "get" {
		return nil, errors.New("--auth-http-request-method must be post or get")
	}

	for _, v := range opts.E2EProcessingLatencyPercentiles {
		if v <= 0 || v > 1 {
			return nil, fmt.Errorf("invalid E2E processing latency percentile: %v", v)
		}
	}

	n.logf(LOG_INFO, version.String("nsqd"))
	n.logf(LOG_INFO, "ID: %d", opts.ID)

	n.tcpServer = &tcpServer{nsqd: n}
	n.tcpListener, err = net.Listen(util.TypeOfAddr(opts.TCPAddress), opts.TCPAddress)
	if err != nil {
		return nil, fmt.Errorf("listen (%s) failed - %s", opts.TCPAddress, err)
	}
	if opts.HTTPAddress != "" {
		n.httpListener, err = net.Listen(util.TypeOfAddr(opts.HTTPAddress), opts.HTTPAddress)
		if err != nil {
			return nil, fmt.Errorf("listen (%s) failed - %s", opts.HTTPAddress, err)
		}
	}
	if n.tlsConfig != nil && opts.HTTPSAddress != "" {
		n.httpsListener, err = tls.Listen("tcp", opts.HTTPSAddress, n.tlsConfig)
		if err != nil {
			return nil, fmt.Errorf("listen (%s) failed - %s", opts.HTTPSAddress, err)
		}
	}
	if opts.BroadcastHTTPPort == 0 {
		tcpAddr, ok := n.RealHTTPAddr().(*net.TCPAddr)
		if ok {
			opts.BroadcastHTTPPort = tcpAddr.Port
		}

View on GitHub (pinned to 85cf10c09c)

Solutions

  1. Find and stop the current holder: `ss -ltnp 'sport = :4150'` or `lsof -iTCP:4150 -sTCP:LISTEN`, then kill it or wait for it to exit.
  2. If two nsqd nodes must coexist, give each its own port: --tcp-address=0.0.0.0:4152 (plus matching --http-address/--https-address).
  3. Verify the address format is host:port (e.g. 0.0.0.0:4150 or 127.0.0.1:4150) with no scheme prefix.
  4. For privileged ports, pick >=1024 or run under setcap/systemd socket activation.

Example fix

# before
nsqd  # second instance, default 0.0.0.0:4150 already taken

# after
nsqd --tcp-address=0.0.0.0:4152 --http-address=0.0.0.0:4153
Defensive patterns

Strategy: validation

Validate before calling

// Go: probe the port before starting nsqd
if ln, err := net.Listen("tcp", opts.TCPAddress); err != nil {
    return fmt.Errorf("tcp address %s unavailable: %w", opts.TCPAddress, err)
} else { ln.Close() }

Try / catch

if n, err := nsqd.New(opts); err != nil {
    if strings.Contains(err.Error(), "listen (") {
        // inspect wrapped cause: address in use / permission / bad address
    }
    return err
}

Prevention

When it happens

Trigger: Another nsqd (or any process) already bound 4150; binding a privileged port (<1024) as non-root; passing a malformed address like '4150' or 'tcp://0.0.0.0:4150' (must be host:port); --tcp-address=0.0.0.0:4150 inside a container where the port is already forwarded; net.Listen with a network type derived via util.TypeOfAddr that does not match the string.

Common situations: Running a second nsqd instance with default flags on the same host; a crashed nsqd whose socket lingers briefly (TIME_WAIT/backlog); systemd/docker restart races; typo'd --tcp-address in a supervisor config; running as an unprivileged user after someone changed the port to 72.

Related errors


AI-assisted analysis of nsqio/nsq@85cf10c09c (2026-08-16). Data as JSON: /api/errors/2411831dfd8dc1c2. Report an issue: GitHub.