{"record":{"id":"9194e1a55902f2da","repo":"AdguardTeam/AdGuardHome","slug":"dhcpv6-ra-icmp-listenpacket-w","errorCode":null,"errorMessage":"dhcpv6 ra: icmp.ListenPacket: %w","messagePattern":"dhcpv6 ra: icmp\\.ListenPacket: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/dhcpd/routeradv.go","lineNumber":257,"sourceCode":"\t\totherConfiguration:          !ra.raSLAACOnly,\n\t\tmtu:                         uint32(ra.iface.MTU),\n\t\tprefixLen:                   64,\n\t\trecursiveDNSServer:          ra.dnsIPAddr,\n\t\tsourceLinkLayerAddress:      ra.iface.HardwareAddr,\n\t}\n\tparams.prefix = make([]byte, 16)\n\tcopy(params.prefix, ra.prefixIPAddr[:8]) // /64\n\n\tvar data []byte\n\tdata, err = createICMPv6RAPacket(params)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"creating packet: %w\", err)\n\t}\n\n\tipAndScope := ra.ipAddr.String() + \"%\" + ra.ifaceName\n\tra.conn, err = icmp.ListenPacket(\"ip6:ipv6-icmp\", ipAndScope)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dhcpv6 ra: icmp.ListenPacket: %w\", err)\n\t}\n\n\tdefer func() {\n\t\tif err != nil {\n\t\t\terr = errors.WithDeferred(err, ra.Close())\n\t\t}\n\t}()\n\n\tcon6 := ra.conn.IPv6PacketConn()\n\n\tif err = con6.SetHopLimit(255); err != nil {\n\t\treturn fmt.Errorf(\"dhcpv6 ra: SetHopLimit: %w\", err)\n\t}\n\n\tif err = con6.SetMulticastHopLimit(255); err != nil {\n\t\treturn fmt.Errorf(\"dhcpv6 ra: SetMulticastHopLimit: %w\", err)\n\t}\n","sourceCodeStart":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/dhcpd/routeradv.go#L239-L275","documentation":"Raised during router-advertisement Init when icmp.ListenPacket(\"ip6:ipv6-icmp\", addr%iface) fails to open the ICMPv6 listening socket. Typical wrapped causes: permission denied (unprivileged process can't open raw ICMPv6 sockets), no IPv6 support in the kernel, or the address/interface not being available. On failure the deferred Close cleans up the partially-initialized RA.","triggerScenarios":"Enabling DHCPv6 RA in a process lacking CAP_NET_RAW or running as non-root on hosts where unprivileged ICMPv6 sockets are disabled (net.ipv4.ping_group_range does not cover ip6:ipv6-icmp usage); IPv6 compiled out (net.ipv6.disable_ipv6=1); interface down at start.","commonSituations":"Docker containers without NET_RAW; hardened sysctl disabling IPv6; VPS with IPv6 removed; interface brought up after AdGuard Home starts.","solutions":["Grant capabilities: run as root or setcap 'cap_net_raw=eip' on the binary (and NET_ADMIN if needed)","Enable IPv6: sysctl -w net.ipv6.disable_ipv6=0 and ensure the interface has an IPv6 address","Ensure the RA interface is up before AdGuard Home starts (add ordering dependency in systemd)","If IPv6/RA is not needed, disable DHCPv6 and RA in the config so Init is never called"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"func canOpenICMPv6(iface string) bool {\n\tc, err := icmp.ListenPacket(\"ip6:ipv6-icmp\", \"::%\"+iface)\n\tif err != nil { return false }\n\tc.Close()\n\treturn true\n}","typeGuard":null,"tryCatchPattern":"if err := ra.Init(...); err != nil {\n    if strings.Contains(err.Error(), \"icmp.ListenPacket\") {\n        if os.IsPermission(err) || strings.Contains(err.Error(), \"permission denied\") {\n            // escalate capabilities or run as root, then retry\n        }\n        // otherwise IPv6 disabled: skip RA and continue without it\n    }\n}","preventionTips":["Run with CAP_NET_RAW (setcap cap_net_raw=eip) or as root","Ensure net.ipv6.disable_ipv6=0 and the interface has an IPv6 address before start","Order service startup after network-online.target","Disable DHCPv6/RA on hosts that don't need it"],"tags":["dhcp","ipv6","icmpv6","socket-bind","permissions","router-advertisement"],"backgroundTag":"raw-socket-permission-denied","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}