stamparm/maltrail · error
unable to open a remote logging socket for
Error message
unable to open a remote logging socket for '{endpoint}' What it means
The sensor could not bind a local UDP socket needed to send remote logging datagrams for this endpoint. Previously such bind failures were silently swallowed; now the sensor logs this error, increments remote_log_errors, and drops the event's datagram.
Solutions
- Check whether the required address family is available (ip addr / `ip -6 addr`); disable v6 remote logging or add v6 connectivity if is_v6 fails on a v4-only host.
- Check for port/address conflicts with ss -lunp and stop the conflicting process or change the configured bind address.
- Ensure the sensor process has network bind permission (containers: add CAP_NET_RAW/NET_BIND_SERVICE or adjust sandbox policy).
- Watch remote_log_errors metrics; bind failures persist until the environment is fixed since each event re-attempts the bind.
Defensive patterns
Strategy: validation
Validate before calling
# before starting the sensor, confirm both address families can bind ip -4 addr show | grep -q inet || echo "no IPv4" ip -6 addr show | grep -q inet6 || echo "no IPv6 (v6 remote logging will fail)" ss -lunp | grep "<bind-port>" # detect address-in-use conflicts
Prevention
- Only enable IPv6 remote logging on hosts with IPv6 connectivity
- Grant the sensor container/process network bind capabilities
- Pick a non-conflicting local bind address/port in configuration
- Test remote logging after network or sandbox policy changes
When it happens
Trigger: send_datagram finds self.sock4/sock6 is None for the required address family and UdpSocket::bind(bind) fails or returns None — e.g. the requested local bind address/port is unavailable, or the address family is not configured on the host (no IPv6 support while endpoint resolves to v6).
Common situations: Host lacks IPv6 (no v6 interfaces) but the endpoint is v6; another process holds the bound port (address in use); sandbox/container without the network capability to bind; restrictive SELinux/AppArmor policy.
Related errors
AI-assisted analysis of stamparm/maltrail@77cfb06d76 (2026-09-13).
Data as JSON: /api/errors/8d1cc0c2f8c2dd77.
Report an issue: GitHub.
Appendix: source
Thrown at sensor/src/output.rs:498
}
}
}
fn send_datagram(&mut self, endpoint: &str, data: &[u8]) {
let Some(addr) = self.endpoint_addr(endpoint) else {
self.remote_log_errors += 1;
return;
};
let is_v6 = addr.is_ipv6();
let bind: &str = if is_v6 { "[::]:0" } else { "0.0.0.0:0" };
let sock = if is_v6 { &mut self.sock6 } else { &mut self.sock4 };
if sock.is_none() {
*sock = UdpSocket::bind(bind).ok();
}
let Some(s) = sock.as_ref() else {
// A socket that will not bind used to be swallowed by `.ok()` and an early return.
log_error(&format!("unable to open a remote logging socket for '{endpoint}'"), true);
self.remote_log_errors += 1;
return;
};
if s.send_to(data, addr).is_err() {
// Drop and recreate the socket once, exactly like `_send_datagram`.
let fresh = UdpSocket::bind(bind).ok();
let retried = match &fresh {
Some(f) => f.send_to(data, addr).is_ok(),
None => false,
};
if is_v6 {
self.sock6 = fresh;
} else {
self.sock4 = fresh;
}
if !retried {
// The second failure used to be discarded outright, so a remote-only deployment
// could lose every event while `events_written` kept climbing.View on GitHub (pinned to 77cfb06d76)