{"record":{"id":"381f3aa7c5770c15","repo":"AdguardTeam/AdGuardHome","slug":"failed-to-get-addresses-for-interface-s-w","errorCode":null,"errorMessage":"failed to get addresses for interface %s: %w","messagePattern":"failed to get addresses for interface (.+?): %w","errorType":"http","errorClass":null,"httpStatus":500,"severity":"warning","filePath":"internal/dhcpd/http_unix.go","lineNumber":470,"sourceCode":"\t\tif jsonIface != nil {\n\t\t\tresp[iface.Name] = jsonIface\n\t\t}\n\t}\n\n\taghhttp.WriteJSONResponseOK(ctx, l, w, r, resp)\n}\n\n// newNetInterfaceJSON creates a JSON object from a [net.Interface] iface.\n// l and cmdCons must not be nil.\nfunc newNetInterfaceJSON(\n\tctx context.Context,\n\tl *slog.Logger,\n\tiface net.Interface,\n\tcmdCons executil.CommandConstructor,\n) (out *netInterfaceJSON, err error) {\n\taddrs, err := iface.Addrs()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\n\t\t\t\"failed to get addresses for interface %s: %w\",\n\t\t\tiface.Name,\n\t\t\terr,\n\t\t)\n\t}\n\n\tout = &netInterfaceJSON{\n\t\tName:         iface.Name,\n\t\tHardwareAddr: iface.HardwareAddr.String(),\n\t}\n\n\tif iface.Flags != 0 {\n\t\tout.Flags = iface.Flags.String()\n\t}\n\n\t// We don't want link-local addresses in JSON, so skip them.\n\tfor _, addr := range addrs {\n\t\tipNet, ok := addr.(*net.IPNet)","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/dhcpd/http_unix.go#L452-L488","documentation":"Thrown by newNetInterfaceJSON when the Go standard library's net.Interface.Addrs() fails while enumerating a network interface for GET /control/dhcp/interfaces. The wrapped syscall error usually reports a deleted interface (ENODEV), permission problems, or a /proc/net state that changed during enumeration.","triggerScenarios":"Calling GET /control/dhcp/interfaces while an interface (VPN tun, docker veth, USB NIC) is being created or destroyed, so Addrs() races with the interface disappearing; or running in a restricted container where reading interface addresses is denied.","commonSituations":"Dashboard loading the DHCP page exactly when a VPN connects/disconnects; Docker/Kubernetes environments with ephemeral veth devices; chroots without /proc mounted; heavily transient network namespaces.","solutions":["Retry the request — transient interface churn usually resolves within milliseconds","If it persists, check the named interface still exists with ip link show <name>","In containers, ensure /proc is mounted and the runtime grants network visibility (e.g. don't use a network-degraded sandbox)","Avoid triggering the interfaces endpoint in tight loops while scripts are flapping interfaces"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if _, err := net.InterfaceByName(iface.Name); err != nil {\n    return // interface vanished; skip it instead of calling Addrs\n}","typeGuard":null,"tryCatchPattern":"var out *netInterfaceJSON\nvar err error\nfor i := 0; i < 3; i++ {\n    out, err = newNetInterfaceJSON(log, iface, cmdCons)\n    if err == nil { break }\n    time.Sleep(50 * time.Millisecond)\n}","preventionTips":["Treat interface enumeration as best-effort: skip failed interfaces instead of failing the whole list","Retry once on transient ENODEV during interface churn","Pin down when interfaces flap (VPN scripts) and avoid querying during those windows"],"tags":["dhcp","network","interface-enumeration","race-condition","linux"],"backgroundTag":"network-interface-unavailable","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}