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
- Find the holder: `ss -ltnp 'sport = :4160'`; stop it or assign a free port: --tcp-address=0.0.0.0:4162.
- Ensure --tcp-address and --http-address differ.
- Confirm the value is host:port (e.g. 0.0.0.0:4160), no scheme prefix.
- 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
- Default lookup ports are 4160/4161 — keep them exclusive to nsqlookupd.
- When running two lookups per host (rare), offset both ports consistently.
- Add readiness checks (nc -z host 4160) before starting nsqd/nsqadmin that talk to it.
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
- listen (%s) failed - %s
- listen (%s) failed - %s
- failed to query any nsqlookupd: %s
- failed to append certificate to pool
- unknown tlsVersionOption %q
AI-assisted analysis of nsqio/nsq@85cf10c09c (2026-08-16).
Data as JSON: /api/errors/95c44f30683a5050.
Report an issue: GitHub.