probelabs/goreplay · warning

promiscuous mode error: %q, interface: %q

Error message

promiscuous mode error: %q, interface: %q

What it means

If config.Promiscuous is true, PcapHandle calls inactive.SetPromisc; failure is wrapped as "promiscuous mode error: <err>, interface: <name>". Enabling promiscuous mode makes the interface pass all frames to the socket; the error means libpcap could not set that option on the inactive handle before activation.

Source

Thrown at internal/capture/capture.go:422

	var inactive *pcap.InactiveHandle
	inactive, err = pcap.NewInactiveHandle(ifi.Name)
	if err != nil {
		return nil, fmt.Errorf("inactive handle error: %q, interface: %q", err, ifi.Name)
	}
	defer inactive.CleanUp()

	if l.config.TimestampType != "" && l.config.TimestampType != "go" {
		var ts pcap.TimestampSource
		ts, err = pcap.TimestampSourceFromString(l.config.TimestampType)
		fmt.Println("Setting custom Timestamp Source. Supported values: `go`, ", inactive.SupportedTimestamps())
		err = inactive.SetTimestampSource(ts)
		if err != nil {
			return nil, fmt.Errorf("%q: supported timestamps: %q, interface: %q", err, inactive.SupportedTimestamps(), ifi.Name)
		}
	}
	if l.config.Promiscuous {
		if err = inactive.SetPromisc(l.config.Promiscuous); err != nil {
			return nil, fmt.Errorf("promiscuous mode error: %q, interface: %q", err, ifi.Name)
		}
	}
	if l.config.Monitor {
		if err = inactive.SetRFMon(l.config.Monitor); err != nil && !errors.Is(err, pcap.CannotSetRFMon) {
			return nil, fmt.Errorf("monitor mode error: %q, interface: %q", err, ifi.Name)
		}
	}

	var snap int

	if !l.config.Snaplen {
		infs, _ := net.Interfaces()
		for _, i := range infs {
			if i.Name == ifi.Name {
				snap = i.MTU + 200
			}
		}
	}

View on GitHub (pinned to 251e45abd2)

Solutions

  1. Run the capture process with CAP_NET_RAW/root so libpcap can apply socket options
  2. Set config.Promiscuous = false if the capture does not strictly need all traffic
  3. Test the interface type; skip promiscuous for loopback/tunnel devices
  4. Capture the underlying wrapped error (%q) to see the libpcap cause

Example fix

// before
cfg.Promiscuous = true // fails on unsupported iface
// after
if isLoopbackOrTunnel(iface) {
    cfg.Promiscuous = false
}
Defensive patterns

Strategy: validation

Validate before calling

if cfg.Promiscuous {
    if i, err := net.InterfaceByName(cfg.Iface); err != nil || i.Flags&net.FlagLoopback != 0 {
        cfg.Promiscuous = false
    }
}

Try / catch

handle, err := l.PcapHandle(ifi)
if err != nil && strings.Contains(err.Error(), "promiscuous mode error") {
    log.Warnf("promiscuous unavailable on %s, retrying without: %v", ifi.Name, err)
    cfg.Promiscuous = false
    handle, err = l.PcapHandle(ifi)
}

Prevention

When it happens

Trigger: Configuring l.config.Promiscuous = true and SetPromisc returning an error, typically when the handle/interface is in a state that cannot accept the option or on platforms where the ioctl fails.

Common situations: Capturing on a device that does not support promiscuous mode (e.g. some tunnels/loopback); running without sufficient privileges in restricted environments; wrappers where SetPromisc is unimplemented.

Related errors


AI-assisted analysis of probelabs/goreplay@251e45abd2 (2026-09-02). Data as JSON: /api/errors/7e01300570fd5e4e. Report an issue: GitHub.