{"record":{"id":"95c44f30683a5050","repo":"nsqio/nsq","slug":"listen-s-failed-s-95c44f","errorCode":null,"errorMessage":"listen (%s) failed - %s","messagePattern":"listen \\((.+?)\\) failed - (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"nsqlookupd/nsqlookupd.go","lineNumber":42,"sourceCode":"}\n\nfunc New(opts *Options) (*NSQLookupd, error) {\n\tvar err error\n\n\tif opts.Logger == nil {\n\t\topts.Logger = log.New(os.Stderr, opts.LogPrefix, log.Ldate|log.Ltime|log.Lmicroseconds)\n\t}\n\tl := &NSQLookupd{\n\t\topts: opts,\n\t\tDB:   NewRegistrationDB(),\n\t}\n\n\tl.logf(LOG_INFO, version.String(\"nsqlookupd\"))\n\n\tl.tcpServer = &tcpServer{nsqlookupd: l}\n\tl.tcpListener, err = net.Listen(\"tcp\", opts.TCPAddress)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"listen (%s) failed - %s\", opts.TCPAddress, err)\n\t}\n\tl.httpListener, err = net.Listen(\"tcp\", opts.HTTPAddress)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"listen (%s) failed - %s\", opts.HTTPAddress, err)\n\t}\n\n\treturn l, nil\n}\n\n// Main starts an instance of nsqlookupd and returns an\n// error if there was a problem starting up.\nfunc (l *NSQLookupd) Main() error {\n\texitCh := make(chan error)\n\tvar once sync.Once\n\texitFunc := func(err error) {\n\t\tonce.Do(func() {\n\t\t\tif err != nil {\n\t\t\t\tl.logf(LOG_FATAL, \"%s\", err)","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/nsqio/nsq/blob/85cf10c09c6c3c86160d6f0eb156f62d0efc1648/nsqlookupd/nsqlookupd.go#L24-L60","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nnsqlookupd  # second instance, 4160 taken\n\n# after\nnsqlookupd --tcp-address=0.0.0.0:4162 --http-address=0.0.0.0:4163","handlingStrategy":"validation","validationCode":"if ln, err := net.Listen(\"tcp\", opts.TCPAddress); err != nil {\n    return fmt.Errorf(\"nsqlookupd tcp %s unavailable: %w\", opts.TCPAddress, err)\n} else { ln.Close() }","typeGuard":null,"tryCatchPattern":"if _, err := nsqlookupd.New(opts); err != nil {\n    var oe *net.OpError\n    if errors.As(err, &oe) && oe.Op == \"listen\" { /* free the port or change --tcp-address */ }\n}","preventionTips":["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."],"tags":["nsqlookupd","network","listen","port-in-use","startup","tcp"],"backgroundTag":null,"analyzedSha":"85cf10c09c6c3c86160d6f0eb156f62d0efc1648","analyzedAt":"2026-08-16T00:53:05.009Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}