{"record":{"id":"ce6a23f01e1d574f","repo":"AdguardTeam/AdGuardHome","slug":"interface-s-has-no-ipv4-addresses","errorCode":null,"errorMessage":"interface %s has no ipv4 addresses","messagePattern":"interface (.+?) has no ipv4 addresses","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/aghnet/dhcp_unix.go","lineNumber":74,"sourceCode":"\t\tvar ip net.IP\n\t\tvar maskLen int\n\t\tswitch a := a.(type) {\n\t\tcase *net.IPAddr:\n\t\t\tip = a.IP\n\t\t\tmaskLen, _ = ip.DefaultMask().Size()\n\t\tcase *net.IPNet:\n\t\t\tip = a.IP\n\t\t\tmaskLen, _ = a.Mask.Size()\n\t\tdefault:\n\t\t\tcontinue\n\t\t}\n\n\t\tif ip = ip.To4(); ip != nil {\n\t\t\treturn netip.PrefixFrom(netip.AddrFrom4([4]byte(ip)), maskLen), nil\n\t\t}\n\t}\n\n\treturn netip.Prefix{}, fmt.Errorf(\"interface %s has no ipv4 addresses\", iface.Name)\n}\n\n// checkOtherDHCPv4 sends a DHCP request to the specified network interface, and\n// waits for a response for a period defined by defaultDiscoverTime.  l must not\n// be nil.\nfunc checkOtherDHCPv4(\n\tctx context.Context,\n\tl *slog.Logger,\n\tiface *net.Interface,\n) (ok bool, err error) {\n\tvar subnet netip.Prefix\n\tif subnet, err = ifaceIPv4Subnet(iface); err != nil {\n\t\treturn false, err\n\t}\n\n\t// Resolve broadcast addr.\n\tdst := netip.AddrPortFrom(BroadcastFromPref(subnet), 67).String()\n\tvar dstAddr *net.UDPAddr","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/aghnet/dhcp_unix.go#L56-L92","documentation":"handlePatchSettingsHTTP failed to JSON-decode the request body into ReqPatchSettingsHTTP. Like the DNS variant, this is a malformed client request: invalid JSON, wrong field types, or empty body on the HTTP-settings PATCH endpoint.","triggerScenarios":"PATCHing the HTTP/web-interface settings endpoint with syntactically invalid JSON or fields whose types don't match the expected struct (e.g. a number where a string address is expected).","commonSituations":"Automated scripts sending unescaped JSON; API version mismatch where field types changed; truncated request bodies behind a misconfigured proxy.","solutions":["Lint the JSON payload before sending","Check ReqPatchSettingsHTTP field types in the API docs and match them","Ensure proxies don't truncate bodies and Content-Type is application/json","Use the web UI to change settings while debugging the raw request"],"exampleFix":"// before\ncurl -X PATCH http://host/control/http_config -d '{\"port\": \"80\"}'\n// after\ncurl -X PATCH http://host/control/http_config \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"port\": 80}'","handlingStrategy":"validation","validationCode":"var req ReqPatchSettingsHTTP\nif err := json.Unmarshal(body, &req); err != nil { return err }","typeGuard":"func isValidPatchHTTP(body []byte) bool {\n    var r ReqPatchSettingsHTTP\n    return json.Unmarshal(body, &r) == nil\n}","tryCatchPattern":"if resp.StatusCode >= 400 {\n    // decode error payload; malformed JSON is caller's fault — fix body\n}","preventionTips":["Marshal request structs instead of hand-writing JSON","Set Content-Type and complete bodies through proxies","Test PATCH endpoints with contract tests"],"tags":["http","json","request-validation","go"],"backgroundTag":"json-decode-failed","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}