{"record":{"id":"55ce8fc7dc5a8e20","repo":"prometheus/node_exporter","slug":"couldn-t-connect-netlink-w","errorCode":null,"errorMessage":"couldn't connect netlink: %w","messagePattern":"couldn't connect netlink: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"collector/tcpstat_linux.go","lineNumber":162,"sourceCode":"\t\t\ttcpStats[st] += value\n\t\t}\n\t}\n\n\tfor st, value := range tcpStats {\n\t\tch <- c.desc.mustNewConstMetric(value, st.String())\n\t}\n\n\treturn nil\n}\n\nfunc getTCPStats(family uint8) (map[tcpConnectionState]float64, error) {\n\tconst TCPFAll = 0xFFF\n\tconst InetDiagInfo = 2\n\tconst SockDiagByFamily = 20\n\n\tconn, err := netlink.Dial(syscall.NETLINK_INET_DIAG, nil)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"couldn't connect netlink: %w\", err)\n\t}\n\tdefer conn.Close()\n\n\tmsg := netlink.Message{\n\t\tHeader: netlink.Header{\n\t\t\tType:  SockDiagByFamily,\n\t\t\tFlags: syscall.NLM_F_REQUEST | syscall.NLM_F_DUMP,\n\t\t},\n\t\tData: (&InetDiagReqV2{\n\t\t\tFamily:   family,\n\t\t\tProtocol: syscall.IPPROTO_TCP,\n\t\t\tStates:   TCPFAll,\n\t\t\tExt:      0 | 1<<(InetDiagInfo-1),\n\t\t}).Serialize(),\n\t}\n\n\tmessages, err := conn.Execute(msg)\n\tif err != nil {","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/prometheus/node_exporter/blob/17ddd77c59ba27e1508e9f7894b1e55b44d6aed3/collector/tcpstat_linux.go#L144-L180","documentation":"getTCPStats opens a netlink socket with netlink.Dial(syscall.NETLINK_INET_DIAG, nil) to issue sock_diag queries. If the socket cannot be created or connected, this wrapped error is returned. Without this socket, TCP state counting (ESTABLISHED, LISTEN, etc.) cannot be performed at all.","triggerScenarios":"netlink.Dial(NETLINK_INET_DIAG) fails: no permission to open netlink sockets (SELinux/seccomp/AppArmor), socket exhaustion (EMFILE/ENFILE), or the kernel lacks NETLINK_INET_DIAG support.","commonSituations":"Strict container runtimes (gVisor, Kata, minimal seccomp profiles) that block socket(AF_NETLINK); fd limits exhausted under load; security modules denying netlink usage for the node_exporter user.","solutions":["Check seccomp/apparmor logs for blocked socket(AF_NETLINK) calls and allow them or use a permissive profile","Raise fd limits if EMFILE/ENFILE is the wrapped cause (ulimit -n, systemd LimitNOFILE)","Run the exporter with sufficient privileges/capabilities in the container runtime","Fall back to dropping --collector.tcpstat if the environment cannot permit netlink"],"exampleFix":"// gVisor runsc blocks netlink by default\n// before: runsc seccomp default denies AF_NETLINK\n// after: use --profile=custom allowing socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG) or run without gVisor","handlingStrategy":"try-catch","validationCode":"conn, err := netlink.Dial(syscall.NETLINK_INET_DIAG, nil)\nif err != nil { /* netlink unusable here — skip tcpstat */ } else { conn.Close() }","typeGuard":null,"tryCatchPattern":"if err := coll.Update(ch); err != nil {\n    var nerr net.Error\n    if errors.As(err, &nerr) || errors.Is(err, os.ErrPermission) {\n        log.Warn(\"netlink dial blocked; falling back\")\n    }\n}","preventionTips":["Run seccomp/apparmor profiles that allow AF_NETLINK sockets","Raise RLIMIT_NOFILE for the exporter under heavy load","Avoid runtimes (gVisor, hardened sandboxes) that block netlink on monitoring hosts","Keep the tcpstat collector disabled where netlink is not permitted"],"tags":["netlink","socket","linux","tcp"],"backgroundTag":"connection-refused","analyzedSha":"17ddd77c59ba27e1508e9f7894b1e55b44d6aed3","analyzedAt":"2026-09-07T17:54:06.211Z","contentChangedAt":"2026-09-07T17:54:06.211Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}