{"record":{"id":"0c05ac53f3ac6584","repo":"AdguardTeam/AdGuardHome","slug":"dialing-v4-w","errorCode":null,"errorMessage":"dialing v4: %w","messagePattern":"dialing v4: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/ipset/ipset_linux.go","lineNumber":219,"sourceCode":"}\n\n// ipInIpsetEntry is the type for entries in [manager.addIPs].\ntype ipInIpsetEntry struct {\n\tipsetName string\n\t// TODO(schzen):  Use netip.Addr.\n\tipArr [net.IPv6len]byte\n}\n\n// dialNetfilter establishes connections to Linux's netfilter module.\nfunc (m *manager) dialNetfilter(conf *netlink.Config) (err error) {\n\t// The kernel API does not actually require two sockets but package\n\t// github.com/digineo/go-ipset does.\n\t//\n\t// TODO(a.garipov): Perhaps we can ditch package ipset altogether and just\n\t// use packages netfilter and netlink.\n\tm.ipv4Conn, err = m.dial(netfilter.ProtoIPv4, conf)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dialing v4: %w\", err)\n\t}\n\n\tm.ipv6Conn, err = m.dial(netfilter.ProtoIPv6, conf)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dialing v6: %w\", err)\n\t}\n\n\treturn nil\n}\n\n// parseIpsetConfigLine parses one ipset configuration line.\nfunc parseIpsetConfigLine(confStr string) (hosts, ipsetNames []string, err error) {\n\tconfStr = strings.TrimSpace(confStr)\n\thostsAndNames := strings.Split(confStr, \"/\")\n\tif len(hostsAndNames) != 2 {\n\t\treturn nil, nil, fmt.Errorf(\"invalid value %q: expected one slash\", confStr)\n\t}\n","sourceCodeStart":201,"sourceCodeEnd":237,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/ipset/ipset_linux.go#L201-L237","documentation":"Raised when the ipset manager fails to open a netfilter socket for the IPv4 protocol during initialization. The manager dials both v4 and v6 netfilter connections; failure on the v4 dial aborts manager creation. Almost always indicates the process lacks CAP_NET_ADMIN or the kernel netfilter subsystem is unavailable.","triggerScenarios":"Calling newManager/newManagerWithDialer on a host where socket(AF_NETLINK, NETLINK_NETFILTER) fails for ProtoIPv4: missing capabilities in a container, netfilter modules not loaded, or a restricted seccomp/apparmor profile.","commonSituations":"Running AdGuard Home in Docker without NET_ADMIN capability, running in an unprivileged LXC container, running on a kernel built without netfilter/ipset modules.","solutions":["Run the binary with CAP_NET_ADMIN (docker: --cap-add=NET_ADMIN, or set cap on the binary)","Verify ipset support: 'lsmod | grep ip_set' or 'ipset list' works on the host","Disable the ipset feature in config if the environment cannot support it"],"exampleFix":"# before\ndocker run adguard/adguardhome\n# after\ndocker run --cap-add=NET_ADMIN adguard/adguardhome","handlingStrategy":"validation","validationCode":"func canUseNetfilter() bool {\n\tconn, err := netlink.Dial(netlink.NETLINK_NETFILTER, nil)\n\tif err != nil {\n\t\treturn false\n\t}\n\t_ = conn.Close()\n\treturn true\n}","typeGuard":null,"tryCatchPattern":"err := mgr.Start(); if err != nil && strings.Contains(err.Error(), \"dialing v4\") { log.Warn(\"netfilter unavailable; disabling ipset\") }","preventionTips":["Deploy with CAP_NET_ADMIN granted to the binary or container","Smoke-test 'ipset list' in the target environment before enabling the feature"],"tags":["ipset","netfilter","linux","permissions"],"backgroundTag":"netfilter-permission-denied","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}