prometheus/node_exporter · error
could not get net class info
Error message
could not get net class info: %w
What it means
After fetching link modes, the netclass collector calls getNetClassInfoRTNL(), which performs an rtnetlink dump of all interfaces (RTM_GETLINK). Any failure there — socket creation, dump request, or message parsing — is wrapped as 'could not get net class info' and aborts the netclass Update entirely, since most attributes come from this netlink dump.
Solutions
- Check that /proc and /sys are mounted in the container (node_exporter requires them) and that socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE) is permitted by the sandbox.
- Run `ip link show` in the same environment to confirm rtnetlink works at all; if it does, upgrade node_exporter to pick up rtnetlink library fixes.
- Check process fd limits (ulimit -n) if the exporter has been running a long time.
- Inspect the wrapped inner error (%w) in logs — it names the exact syscall that failed.
- If only netclass fails while other collectors work, test with --collector.netclass in a privileged container to isolate permission issues.
Defensive patterns
Strategy: try-catch
Validate before calling
// sanity check before scraping: rtnetlink dump must work
conn, err := rtnetlink.Dial(nil)
if err != nil { /* netclass will fail */ }
else { _, err = conn.Link.List(); if err != nil { /* abort early */ } } Try / catch
err := collector.Update(ch)
if err != nil && strings.Contains(err.Error(), "could not get net class info") {
logger.Warn("netclass scrape failed", "cause", err)
return // drop this scrape, keep exporter alive
} Prevention
- Mount /proc and /sys in containers and allow NETLINK_ROUTE sockets
- Monitor scrape_error metric per collector to catch recurring rtnetlink failures
- Check fd limits on long-running exporter processes
- Test `ip link show` in the same namespace as the exporter
When it happens
Trigger: getNetClassInfoRTNL() errors: rtnetlink socket open fails (no CAP_NET_ADMIN not required for dump, but seccomp can block socket(AF_NETLINK, NETLINK_ROUTE)), the RTM_GETLINK dump send/receive fails, or rtnetlink.LinkMessages parsing fails on malformed kernel responses.
Common situations: Containers with restricted netlink permissions; kernel/network namespace oddities in restricted VPS environments; procfs/sysfs not mounted so attribute assembly fails downstream; syscall exhaustion (fd limits) in very long-running processes.
Related errors
- couldn't connect rtnetlink
- couldn't get links
- couldn't get routes
- failed to initialize ethtool library
- could not get link modes
AI-assisted analysis of prometheus/node_exporter@17ddd77c59 (2026-09-07).
Data as JSON: /api/errors/ef91c9f0f707398b.
Report an issue: GitHub.
Appendix: source
Thrown at collector/netclass_rtnl_linux.go:64
}
c.logger.Info("ETHTOOL netlink interface unavailable, duplex and linkspeed are not scraped.")
} else {
for _, lm := range lms {
if c.ignoredDevicesPattern.MatchString(lm.Interface.Name) {
continue
}
if lm.SpeedMegabits >= 0 {
speedBytes := uint64(lm.SpeedMegabits * 1000 * 1000 / 8)
pushMetric(ch, c.getFieldDesc("speed_bytes"), speedBytes, prometheus.GaugeValue, lm.Interface.Name)
}
linkModes[lm.Interface.Name] = lm
}
}
// Get most attributes from Netlink
lMsgs, err := c.getNetClassInfoRTNL()
if err != nil {
return fmt.Errorf("could not get net class info: %w", err)
}
relevantLinks := make([]rtnetlink.LinkMessage, 0, len(lMsgs))
for _, msg := range lMsgs {
if !c.ignoredDevicesPattern.MatchString(msg.Attributes.Name) {
relevantLinks = append(relevantLinks, msg)
}
}
// Read sysfs for attributes that Netlink doesn't expose
sysfsAttrs, err := getSysfsAttributes(relevantLinks)
if err != nil {
return fmt.Errorf("could not get sysfs device info: %w", err)
}
// Parse all the info and update metrics
for _, msg := range relevantLinks {
upDesc := prometheus.NewDesc(View on GitHub (pinned to 17ddd77c59)