{"record":{"id":"af9aa90361b3ca4a","repo":"AdguardTeam/AdGuardHome","slug":"parsing-w","errorCode":null,"errorMessage":"parsing: %w","messagePattern":"parsing: %w","errorType":"validation","errorClass":null,"httpStatus":400,"severity":"error","filePath":"internal/dhcpd/http_unix.go","lineNumber":662,"sourceCode":"\n// parseLease parses a lease from r.  If there is no error returns DHCPServer\n// and *Lease.  r must be non-nil.\nfunc (s *server) parseLease(r io.Reader) (srv DHCPServer, lease *dhcpsvc.Lease, err error) {\n\tl := &leaseStatic{}\n\terr = json.NewDecoder(r).Decode(l)\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"decoding json: %w\", err)\n\t}\n\n\tif !l.IP.IsValid() {\n\t\treturn nil, nil, errors.Error(\"invalid ip\")\n\t}\n\n\tl.IP = l.IP.Unmap()\n\n\tlease, err = l.toLease()\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"parsing: %w\", err)\n\t}\n\n\tif lease.IP.Is4() {\n\t\tsrv = s.srv4\n\t} else {\n\t\tsrv = s.srv6\n\t}\n\n\treturn srv, lease, nil\n}\n\n// handleDHCPAddStaticLease is the handler for the POST\n// /control/dhcp/add_static_lease HTTP API.\nfunc (s *server) handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request) {\n\tctx := r.Context()\n\tl := s.conf.Logger\n\n\tsrv, lease, err := s.parseLease(r.Body)","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/dhcpd/http_unix.go#L644-L680","documentation":"Returned by parseLease when the decoded JSON passes initial checks but l.toLease() fails to convert it into a dhcpsvc.Lease. Typical causes are an invalid MAC address or an IP/hostname that violates lease invariants (e.g. multicast/unspecified IP). The wrapped error names the offending field.","triggerScenarios":"Adding/updating a static lease where mac is not 6/8 bytes of valid hex pairs, the hostname contains invalid characters, or the IP (after IPv4/IPv6 unmapping) is not acceptable to the lease constructor (e.g. 0.0.0.0 or multicast).","commonSituations":"Typing a MAC with O instead of 0 or wrong separator style; reserving 0.0.0.0 or a broadcast/multicast address; hostnames with spaces or underscores rejected by validation.","solutions":["Use a canonical MAC format such as AA:BB:CC:DD:EE:FF (verify with a regex or a MAC parser before sending)","Pick a concrete unicast IP inside your DHCP range, never 0.0.0.0, 255.255.255.255, or multicast","Sanitize hostname to RFC-allowed characters (letters, digits, hyphen)","Read the wrapped message — it states exactly which field (mac/ip/hostname) failed"],"exampleFix":"// before\n{\"ip\":\"192.168.1.10\",\"mac\":\"AA:BB:CC:DD:EE:FF\",\"hostname\":\"my printer\"}\n// -> 400 parsing: bad mac\n\n// after\n{\"ip\":\"192.168.1.10\",\"mac\":\"AA:BB:CC:DD:EE:FF\",\"hostname\":\"my-printer\"}","handlingStrategy":"validation","validationCode":"var macRe = regexp.MustCompile(`^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$`)\nfunc leaseOK(ip, mac, hostname string) bool {\n\tp := net.ParseIP(ip)\n\treturn p != nil && p.IsGlobalUnicast() && macRe.MatchString(mac)\n}","typeGuard":null,"tryCatchPattern":"if err := addStaticLease(lease); err != nil {\n    if strings.Contains(err.Error(), \"parsing:\") {\n        // invalid mac/hostname/ip: check wrapped field name and correct it\n    }\n}","preventionTips":["Normalize MACs to colon-separated hex pairs","Reserve only global-unicast IPs inside your pool","Use RFC-valid hostnames (letters, digits, hyphens)"],"tags":["dhcp","validation","mac-address","static-lease"],"backgroundTag":"invalid-mac-address","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}