probelabs/goreplay · error
err.Error()
Error message
err.Error()
What it means
newVXLANHandler opens a UDP socket on the configured VXLAN address/port via net.ListenUDP. If the OS cannot bind the socket, the underlying error is wrapped with fmt.Errorf(err.Error()), losing the error chain and producing an error identical to the raw Go net error (e.g. 'listen udp 0.0.0.0:4789: bind: address already in use'). It surfaces when activateVxLanSocket is called and the listen fails.
Source
Thrown at internal/capture/vxlan.go:33
connection *net.UDPConn
packetChannel chan gopacket.Packet
vnis []int
}
func newVXLANHandler(port int, vnis []int) (*vxlanHandle, error) {
if port == 0 {
port = 4789
}
addr := net.UDPAddr{
Port: port,
IP: net.ParseIP("0.0.0.0"),
}
vxlanHandle := &vxlanHandle{}
con, err := net.ListenUDP("udp", &addr)
if err != nil {
return nil, fmt.Errorf(err.Error())
}
vxlanHandle.connection = con
vxlanHandle.packetChannel = make(chan gopacket.Packet, 1000)
vxlanHandle.vnis = vnis
go vxlanHandle.reader()
return vxlanHandle, nil
}
func (v *vxlanHandle) reader() {
for {
inputBytes := make([]byte, VxLanPacketSize)
length, _, err := v.connection.ReadFromUDP(inputBytes)
if err != nil {
if errors.Is(err, net.ErrClosed) {
return
}
continueView on GitHub (pinned to 251e45abd2)
Solutions
- Find the process holding the port (ss -lunp | grep 4789 or lsof -i :4789) and stop it, or change the configured VXLAN port/address.
- If two agents are intended, run one per host/network namespace instead of binding the same UDP port twice.
- Fix the configured bind address to a valid local IP or 0.0.0.0.
- Ensure the process has permission to bind (capabilities NET_RAW/NET_BIND_SERVICE in containers).
- Improve the code to wrap with %w: fmt.Errorf("vxlan listen: %w", err) to preserve the chain.
Example fix
// before
return nil, fmt.Errorf(err.Error())
// after
return nil, fmt.Errorf("listen vxlan udp %s: %w", addr.String(), err) Defensive patterns
Strategy: validation
Validate before calling
func canBindUDP(addr string) error {
c, err := net.ListenUDP("udp", addr)
if err != nil { return err }
return c.Close()
} Try / catch
h, err := newVXLANHandler(addr, vnis)
if err != nil {
var oe *net.OpError
if errors.As(err, &oe) && strings.Contains(oe.Err.Error(), "address already in use") {
// pick another port or stop the conflicting process
}
return err
} Prevention
- Reserve the VXLAN UDP port exclusively for one agent per host
- Pre-flight bind check before starting capture
- In containers, grant NET_BIND_SERVICE/NET_RAW capabilities
- Wrap errors with %w so the root cause stays inspectable
When it happens
Trigger: Calling activateVxLanSocket when the UDP port is already bound by another process (or another capture instance), when the address is not assignable to a local interface, or when the process lacks permission (e.g. restricted container without NET_BIND_SERVICE on a privileged port).
Common situations: Running two capture agents on the same host against the same VXLAN port (4789 by default); port already taken by another VXLAN listener; running in a container with a too-restrictive securityContext; typo in host address passed in the config.
Related errors
- invalid engine %s
- inactive handle error: %q, interface: %q
- %q: supported timestamps: %q, interface: %q
- promiscuous mode error: %q, interface: %q
- monitor mode error: %q, interface: %q
AI-assisted analysis of probelabs/goreplay@251e45abd2 (2026-09-02).
Data as JSON: /api/errors/75d086857d88e51b.
Report an issue: GitHub.