nsqio/nsq · critical

listen (%s) failed - %s

Error message

listen (%s) failed - %s

What it means

nsqlookupd failed to bind its TCP listener (net.Listen("tcp", opts.TCPAddress), default 0.0.0.0:4160, flag --tcp-address). This socket is how nsqd nodes register themselves and send heartbeat pings. New() wraps the raw net error with the requested address; common causes are port in use, permission denied on privileged ports, or a malformed address string.

Source

Thrown at nsqlookupd/nsqlookupd.go:42

}

func New(opts *Options) (*NSQLookupd, error) {
	var err error

	if opts.Logger == nil {
		opts.Logger = log.New(os.Stderr, opts.LogPrefix, log.Ldate|log.Ltime|log.Lmicroseconds)
	}
	l := &NSQLookupd{
		opts: opts,
		DB:   NewRegistrationDB(),
	}

	l.logf(LOG_INFO, version.String("nsqlookupd"))

	l.tcpServer = &tcpServer{nsqlookupd: l}
	l.tcpListener, err = net.Listen("tcp", opts.TCPAddress)
	if err != nil {
		return nil, fmt.Errorf("listen (%s) failed - %s", opts.TCPAddress, err)
	}
	l.httpListener, err = net.Listen("tcp", opts.HTTPAddress)
	if err != nil {
		return nil, fmt.Errorf("listen (%s) failed - %s", opts.HTTPAddress, err)
	}

	return l, nil
}

// Main starts an instance of nsqlookupd and returns an
// error if there was a problem starting up.
func (l *NSQLookupd) Main() error {
	exitCh := make(chan error)
	var once sync.Once
	exitFunc := func(err error) {
		once.Do(func() {
			if err != nil {
				l.logf(LOG_FATAL, "%s", err)

View on GitHub (pinned to 85cf10c09c)

Solutions

  1. Find the holder: `ss -ltnp 'sport = :4160'`; stop it or assign a free port: --tcp-address=0.0.0.0:4162.
  2. Ensure --tcp-address and --http-address differ.
  3. Confirm the value is host:port (e.g. 0.0.0.0:4160), no scheme prefix.
  4. For privileged ports use capabilities or a high port.

Example fix

# before
nsqlookupd  # second instance, 4160 taken

# after
nsqlookupd --tcp-address=0.0.0.0:4162 --http-address=0.0.0.0:4163
Defensive patterns

Strategy: validation

Validate before calling

if ln, err := net.Listen("tcp", opts.TCPAddress); err != nil {
    return fmt.Errorf("nsqlookupd tcp %s unavailable: %w", opts.TCPAddress, err)
} else { ln.Close() }

Try / catch

if _, err := nsqlookupd.New(opts); err != nil {
    var oe *net.OpError
    if errors.As(err, &oe) && oe.Op == "listen" { /* free the port or change --tcp-address */ }
}

Prevention

When it happens

Trigger: A second nsqlookupd started with default flags on the same host; --tcp-address reusing the HTTP port (4161); binding <1024 without privileges; malformed host:port (missing port, unknown hostname that fails resolution); the interface in the address not present on the host.

Common situations: Running a redundant lookup pair on one box for testing without changing ports; systemd restart race where the old process still holds the socket; containers with duplicate port mappings; ops scripts copying a config and forgetting to bump the port.

Related errors


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