crowdsecurity/crowdsec · error
could not listen on port %d: %w
Error message
could not listen on port %d: %w
What it means
The UDP address resolved but net.ListenUDP failed to bind the socket. Typical causes are the port already in use by another process, binding to an address not assigned to the machine, or lacking privileges for ports below 1024.
Source
Thrown at pkg/acquisition/modules/syslog/internal/server/syslogserver.go:32
conn *net.UDPConn
Logger *log.Entry
MaxMessageLen int
}
type SyslogMessage struct {
Message []byte
Client string
}
func (s *SyslogServer) Listen(listenAddr string, port int) error {
udpAddr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(listenAddr, strconv.Itoa(port)))
if err != nil {
return fmt.Errorf("could not resolve addr %s: %w", listenAddr, err)
}
udpConn, err := net.ListenUDP("udp", udpAddr)
if err != nil {
return fmt.Errorf("could not listen on port %d: %w", port, err)
}
s.Logger.Debugf("listening on %s:%d", listenAddr, port)
s.conn = udpConn
return nil
}
func (s *SyslogServer) Serve(ctx context.Context, msgChan chan SyslogMessage) error {
go func() {
<-ctx.Done()
// closing the socket unblocks ReadFrom()
s.conn.Close()
}()
// RFC3164 says 1024 bytes max
// RFC5424 says 480 bytes minimum, and should support up to 2048 bytes
buf := make([]byte, s.MaxMessageLen)View on GitHub (pinned to 909b515798)
Solutions
- Stop the process already bound to that UDP port (e.g. disable rsyslog's UDP listener) or choose another port.
- For ports <1024, run crowdsec with elevated privileges or CAP_NET_BIND_SERVICE, or use a high port and forward with rsyslog.
- Verify the listen IP is assigned to the host (ip addr); use 0.0.0.0 to bind all interfaces.
- Read the wrapped OS error: 'address already in use' vs 'cannot assign requested address' distinguish the two cases.
Example fix
// before (config.yaml) port: 514 # EACCES as non-root // after port: 5514 # or grant CAP_NET_BIND_SERVICE
Defensive patterns
Strategy: try-catch
Validate before calling
if port < 1024 && os.Geteuid() != 0 {
return errors.New("binding ports <1024 requires root or CAP_NET_BIND_SERVICE")
}
// check availability
if conn, err := net.ListenPacket("udp", fmt.Sprintf("%s:%d", addr, port)); err == nil {
conn.Close()
} else {
return fmt.Errorf("udp port %d unavailable: %w", port, err)
} Try / catch
if err := srv.Listen(addr, port); err != nil {
if strings.Contains(err.Error(), "address already in use") {
// stop competing daemon or pick another port
}
return err
} Prevention
- Disable rsyslog/syslog-ng UDP listeners that compete on 514.
- Use high ports (e.g. 5514) for non-root deployments.
- Verify listen IP exists on the host with 'ip addr' before configuring.
When it happens
Trigger: Stream() -> Listen() with a port already bound by another syslog daemon (rsyslog/syslog-ng), a listen IP not present on the host, or port 514 as an unprivileged user.
Common situations: Running crowdsec as non-root while wanting the standard syslog port 514; rsyslog already holding 514/udp; docker container where 0.0.0.0 bind address differs; typo'd listen IP.
Related errors
- could not resolve addr %s: %w
- reading from socket: %w
- could not close UDP connection: %w
- could not start syslog server: %w
- invalid port %d
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/b395e44da493deb4.
Report an issue: GitHub.