crowdsecurity/crowdsec · error

listening on %s: %w

Error message

listening on %s: %w

What it means

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'.

Source

Thrown at pkg/apiserver/apiserver.go:407

		}

		switch {
		case errors.Is(err, http.ErrServerClosed):
			break
		case err != nil:
			serverError <- err
		}
	}

	// Starting TCP listener
	go func(url string) {
		if url == "" {
			return
		}

		listener, err := listenConfig.Listen(ctx, "tcp", url)
		if err != nil {
			serverError <- fmt.Errorf("listening on %s: %w", url, err)
			return
		}

		log.Infof("CrowdSec Local API listening on %s", url)
		startServer(listener, true)
	}(s.cfg.ListenURI)

	// Starting Unix socket listener
	go func(socket string) {
		if socket == "" {
			return
		}

		if err := os.Remove(socket); err != nil {
			if !errors.Is(err, fs.ErrNotExist) {
				log.Errorf("can't remove socket %s: %s", socket, err)
			}
		}

View on GitHub (pinned to 909b515798)

Solutions

  1. Check for a duplicate process: `ss -ltnp | grep <port>` or `pgrep crowdsec`.
  2. Change api.listen_uri in config.yaml to a free address/port.
  3. For privileged ports, run with CAP_NET_BIND_SERVICE or use a port >1024.
  4. In containers, ensure only one process binds the published port.

Example fix

// before
listen_uri: 0.0.0.0:80
// after
listen_uri: 0.0.0.0:8080
Defensive patterns

Strategy: validation

Validate before calling

addr := cfg.ListenURI
if ln, err := net.Listen("tcp", addr); err != nil {
    return fmt.Errorf("cannot bind %s (in use or no permission?): %w", addr, err)
} else {
    ln.Close()
}

Try / catch

if err := apiServer.Run(ctx, ready); err != nil {
    if strings.Contains(err.Error(), "listening on") {
        log.Fatalf("LAPI bind failed: %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/d8dc95faf513a45d. Report an issue: GitHub.