netbirdio/netbird · error
failed to bind free port for eBPF proxy
Error message
failed to bind free port for eBPF proxy
What it means
Returned by portLookup.searchFreePort when every UDP port in the hardcoded range 3128-3228 (portRangeStart=3128, +100) failed a trial net.ListenPacket("udp", ":port") bind. The eBPF WireGuard proxy needs one free loopback UDP port in this fixed window because the eBPF program is loaded with a specific proxy port that kernel and userspace must agree on. When all 101 candidates are taken, Listen() aborts.
Source
Thrown at client/iface/wgproxy/ebpf/portlookup.go:22
"fmt"
"net"
)
var (
portRangeStart = 3128
portRangeEnd = portRangeStart + 100
)
type portLookup struct {
}
func (pl portLookup) searchFreePort() (int, error) {
for i := portRangeStart; i <= portRangeEnd; i++ {
if pl.tryToBind(i) == nil {
return i, nil
}
}
return 0, fmt.Errorf("failed to bind free port for eBPF proxy")
}
func (pl portLookup) tryToBind(port int) error {
l, err := net.ListenPacket("udp", fmt.Sprintf(":%d", port))
if err != nil {
return err
}
_ = l.Close()
return nil
}
View on GitHub (pinned to 93e97f4bf1)
Solutions
- Find the squatter and stop it: `ss -uapn | awk '$5 ~ /:31[0-9][0-9]|:32[0-2][0-9]/'` or `lsof -i UDP:3128-3228`
- Ensure only one agent instance runs: `pgrep -a netbird` and stop the duplicate service/container
- Free the range and retry starting the agent (the search is only done once per Listen call, so a restart is required)
- If the host legitimately needs those ports, run the agent where the range is free or disable the eBPF path so the userspace UDP proxy is used
Defensive patterns
Strategy: fallback
Validate before calling
// preflight: is the eBPF proxy port window usable?
func proxyRangeFree() bool {
for p := 3128; p <= 3228; p++ {
if l, err := net.ListenPacket("udp", fmt.Sprintf(":%d", p)); err == nil {
_ = l.Close()
return true
}
}
return false
} Try / catch
if err := wgProxy.Listen(); err != nil {
if strings.Contains(err.Error(), "failed to bind free port for eBPF proxy") {
log.Warn("eBPF proxy port window busy, falling back to userspace UDP proxy")
wgProxy = udpProxy // run without eBPF acceleration
} else {
return err
}
} Prevention
- Run exactly one netbird agent per host; check `pgrep -a netbird` before starting
- Reserve UDP 3128-3228 on hosts that run the agent (avoid Squid-style proxies in that window)
- Automate the preflight bind check above in deployment scripts so failures surface before `netbird up`
When it happens
Trigger: WGEBPFProxy.Listen() calling searchFreePort while another process (most commonly a second NetBird agent instance, or Squid, which defaults to TCP/3128 but other proxies scan this range too) holds every UDP port in 3128-3228, or UDP socket creation is blocked (socket/memory limits, seccomp in a hardened container).
Common situations: Two netbird daemons on one host (system service plus manually launched binary); a caching proxy or test suite squatting the 3128 range; containers with very low UDP buffer/socket limits; SELinux/seccomp denying UDP binds.
Related errors
- failed to read UDP packet from WG: %w
- proxy_protocol is not supported for UDP services
- add IP to ipset: %w
- create ipset: %w
- failed to check rule: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/68e46fe53dc24f18.
Report an issue: GitHub.