AlexxIT/go2rtc · error

no interfaces for listen

Error message

no interfaces for listen

What it means

The mDNS client's ListenMulticastUDP walks all host interfaces, creates a UDP socket per eligible interface, and joins the multicast group on each. If none of the interfaces yielded a usable socket (b.Sends stayed nil), there is nothing to multicast on and the function returns this error before creating the receiver.

Solutions

  1. Ensure at least one network interface is up with a valid IPv4 address before starting mDNS discovery (check `ip addr` / `ifconfig`).
  2. If running in Docker, attach the container to a real network (`--network bridge` or `host`) instead of `none` so multicast-capable interfaces exist.
  3. Exclude loopback-only setups: give the host/container an address on the LAN, since loopback does not carry multicast joins the way the code expects.
  4. Retry discovery after network-manager has brought interfaces up (common on freshly booted systems).

Example fix

// before: start discovery immediately at boot before interfaces are up
server.OnConnect(func() { go mdns.Discovery(...) }) // no interfaces for listen

// after: wait for a non-loopback IPv4 interface
waitForNetworkInterface() // poll net.Interfaces() for up, non-loopback IPv4
go mdns.Discovery(...)
Defensive patterns

Strategy: validation

Validate before calling

func hasMulticastCapableInterface() bool {
	ifaces, err := net.Interfaces()
	if err != nil {
		return false
	}
	for _, ifc := range ifaces {
		if ifc.Flags&net.FlagUp == 0 || ifc.Flags&net.FlagLoopback != 0 {
			continue
		}
		addrs, _ := ifc.Addrs()
		for _, a := range addrs {
			if ipn, ok := a.(*net.IPNet); ok && ipn.IP.To4() != nil {
				return true
			}
		}
	}
	return false
}

Try / catch

if !hasMulticastCapableInterface() {
	log.Warn("mdns: no usable multicast interface, skipping discovery")
	return
}
if err := mdnsDiscovery(...); err != nil && strings.Contains(err.Error(), "no interfaces for listen") {
	// retry after delay once network is up
}

Prevention

When it happens

Trigger: Calling mdns Discovery/Serve on a host with no non-loopback interfaces matching the multicast rules — e.g. no network up, all interfaces down, or interfaces whose addresses are filtered out (loopback-only, link-local filtered by code, or IPv6-only where the code expects IPv4).

Common situations: Running go2rtc inside a Docker container launched with `--network none` or no published networks; running in a sandbox/CI without network interfaces; all interfaces administratively down; Windows/macOS VPN adapters filtered out; calling Discovery before the network is up at boot.

Related errors


AI-assisted analysis of AlexxIT/go2rtc@c245815e75 (2026-09-07). Data as JSON: /api/errors/e5db1047a569d592. Report an issue: GitHub.

Appendix: source

Thrown at pkg/mdns/client.go:202

				// 1. Allow multicast UDP to listen concurrently across multiple listeners
				_ = SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
			})
		},
	}

	ctx := context.Background()

	for _, ipn := range nets {
		conn, err := lc1.ListenPacket(ctx, "udp4", ipn.IP.String()+":5353") // same port important
		if err != nil {
			continue
		}
		b.Nets = append(b.Nets, ipn)
		b.Sends = append(b.Sends, conn)
	}

	if b.Sends == nil {
		return errors.New("no interfaces for listen")
	}

	// 3. Create receiver
	lc2 := net.ListenConfig{
		Control: func(network, address string, c syscall.RawConn) error {
			return c.Control(func(fd uintptr) {
				// 1. Allow multicast UDP to listen concurrently across multiple listeners
				_ = SetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)

				// 2. Disable loop responses
				_ = SetsockoptInt(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_LOOP, 0)

				// 3. Allow receive multicast responses on all this addresses
				mreq := &syscall.IPMreq{
					Multiaddr: [4]byte{224, 0, 0, 251},
				}
				_ = SetsockoptIPMreq(fd, syscall.IPPROTO_IP, syscall.IP_ADD_MEMBERSHIP, mreq)

View on GitHub (pinned to c245815e75)