{"record":{"id":"d8dc95faf513a45d","repo":"crowdsecurity/crowdsec","slug":"listening-on-s-w","errorCode":null,"errorMessage":"listening on %s: %w","messagePattern":"listening on (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/apiserver/apiserver.go","lineNumber":407,"sourceCode":"\t\t}\n\n\t\tswitch {\n\t\tcase errors.Is(err, http.ErrServerClosed):\n\t\t\tbreak\n\t\tcase err != nil:\n\t\t\tserverError <- err\n\t\t}\n\t}\n\n\t// Starting TCP listener\n\tgo func(url string) {\n\t\tif url == \"\" {\n\t\t\treturn\n\t\t}\n\n\t\tlistener, err := listenConfig.Listen(ctx, \"tcp\", url)\n\t\tif err != nil {\n\t\t\tserverError <- fmt.Errorf(\"listening on %s: %w\", url, err)\n\t\t\treturn\n\t\t}\n\n\t\tlog.Infof(\"CrowdSec Local API listening on %s\", url)\n\t\tstartServer(listener, true)\n\t}(s.cfg.ListenURI)\n\n\t// Starting Unix socket listener\n\tgo func(socket string) {\n\t\tif socket == \"\" {\n\t\t\treturn\n\t\t}\n\n\t\tif err := os.Remove(socket); err != nil {\n\t\t\tif !errors.Is(err, fs.ErrNotExist) {\n\t\t\t\tlog.Errorf(\"can't remove socket %s: %s\", socket, err)\n\t\t\t}\n\t\t}","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/apiserver/apiserver.go#L389-L425","documentation":"The listen goroutine in Run sends this error when net.Listen (listenConfig.Listen) cannot bind the configured TCP address for the LAPI. This is the actual 'cannot listen' event; Run surfaces it wrapped as 'local API server stopped with error'.","triggerScenarios":"listenConfig.Listen(ctx, \"tcp\", url) fails because the port is taken by another process, the address is not assignable, or binding a privileged port lacks permission.","commonSituations":"Another crowdsec/LAPI instance already running; port 8080/127.0.0.1:80 occupied; listen_uri set to 0.0.0.0:80 in an unprivileged container.","solutions":["Check for a duplicate process: `ss -ltnp | grep <port>` or `pgrep crowdsec`.","Change api.listen_uri in config.yaml to a free address/port.","For privileged ports, run with CAP_NET_BIND_SERVICE or use a port >1024.","In containers, ensure only one process binds the published port."],"exampleFix":"// before\nlisten_uri: 0.0.0.0:80\n// after\nlisten_uri: 0.0.0.0:8080","handlingStrategy":"validation","validationCode":"addr := cfg.ListenURI\nif ln, err := net.Listen(\"tcp\", addr); err != nil {\n    return fmt.Errorf(\"cannot bind %s (in use or no permission?): %w\", addr, err)\n} else {\n    ln.Close()\n}","typeGuard":null,"tryCatchPattern":"if err := apiServer.Run(ctx, ready); err != nil {\n    if strings.Contains(err.Error(), \"listening on\") {\n        log.Fatalf(\"LAPI bind failed: %v\", err)\n    }\n    return err\n}","preventionTips":["Pick a non-default port if you run multiple services on 8080.","Grant CAP_NET_BIND_SERVICE only when binding low ports.","In k8s, use a dedicated containerPort and check for port collisions.","Add a pre-start check that the port is free."],"tags":["network","bind","port"],"backgroundTag":"address-already-in-use","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}