prometheus/node_exporter · error

could not get ARP entries

Error message

could not get ARP entries: %w

What it means

Update wraps failures from the netlink ARP enumeration path with 'could not get ARP entries: %w'. When --collector.arp.netlink is enabled, getTotalArpEntriesRTNL failed (netlink socket or dump error) so no ARP entry counts could be gathered.

Solutions

  1. Disable the netlink path (omit --collector.arp.netlink) to fall back to /proc/net/arp parsing via procfs.
  2. Grant the exporter process CAP_NET_ADMIN / permission to open NETLINK_ROUTE sockets.
  3. Check LSM (SELinux/AppArmor) denials and adjust policy.
  4. Inspect the wrapped error (%w) for the underlying errno.

Example fix

// before
node_exporter --collector.arp.netlink
// after
node_exporter   # uses /proc/net/arp instead
Defensive patterns

Strategy: fallback

Try / catch

if err := c.Update(ch); err != nil {
    var unwrapped error = err
    for errors.Unwrap(unwrapped) != nil { unwrapped = errors.Unwrap(unwrapped) }
    logger.Error("ARP collection failed", "root", unwrapped)
}

Prevention

When it happens

Trigger: arpCollector.Update with --collector.arp.netlink=true when getTotalArpEntriesRTNL returns an error — e.g., netlink socket creation failure or a failed RTM_GETNEIGH dump.

Common situations: Restricted containers/netns lacking NETLINK_ROUTE permissions; SELinux/AppArmor denials on netlink sockets; kernel-level netlink errors under heavy load.

Related errors


AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07). Data as JSON: /api/errors/6a15789fbad93874. Report an issue: GitHub.

Appendix: source

Thrown at collector/arp_linux.go:112

	for _, n := range neighbors {
		// Skip entries which have state NUD_NOARP to conform to output of /proc/net/arp.
		if n.State&unix.NUD_NOARP == 0 {
			entries[n.Interface.Name]++
		}
	}

	return entries, nil
}

func (c *arpCollector) Update(ch chan<- prometheus.Metric) error {
	var enumeratedEntry map[string]uint32

	if *arpNetlink {
		var err error

		enumeratedEntry, err = getTotalArpEntriesRTNL()
		if err != nil {
			return fmt.Errorf("could not get ARP entries: %w", err)
		}
	} else {
		entries, err := c.fs.GatherARPEntries()
		if err != nil {
			return fmt.Errorf("could not get ARP entries: %w", err)
		}

		enumeratedEntry = getTotalArpEntries(entries)
	}

	for device, entryCount := range enumeratedEntry {
		if c.deviceFilter.ignored(device) {
			continue
		}
		ch <- prometheus.MustNewConstMetric(
			arpEntries, prometheus.GaugeValue, float64(entryCount), device)
	}

View on GitHub (pinned to 17ddd77c59)