AdguardTeam/AdGuardHome · error
decoding json: %w
Error message
decoding json: %w
What it means
Returned by parseLease when the JSON body of a static-lease request (add/remove/update) cannot be decoded into leaseStatic. This is a client-side payload problem: malformed JSON, wrong types (e.g. IP given as a number), or truncation. Affects POST /control/dhcp/add_static_lease and friends.
Source
Thrown at internal/dhcpd/http_unix.go:651
} else if found4 {
result.V4.OtherServer.Found = "yes"
}
if err6 != nil {
result.V6.OtherServer.Found = "error"
result.V6.OtherServer.Error = err6.Error()
} else if found6 {
result.V6.OtherServer.Found = "yes"
}
}
// parseLease parses a lease from r. If there is no error returns DHCPServer
// and *Lease. r must be non-nil.
func (s *server) parseLease(r io.Reader) (srv DHCPServer, lease *dhcpsvc.Lease, err error) {
l := &leaseStatic{}
err = json.NewDecoder(r).Decode(l)
if err != nil {
return nil, nil, fmt.Errorf("decoding json: %w", err)
}
if !l.IP.IsValid() {
return nil, nil, errors.Error("invalid ip")
}
l.IP = l.IP.Unmap()
lease, err = l.toLease()
if err != nil {
return nil, nil, fmt.Errorf("parsing: %w", err)
}
if lease.IP.Is4() {
srv = s.srv4
} else {
srv = s.srv6
}View on GitHub (pinned to b41aefbe51)
Solutions
- Validate the JSON before sending: echo '$BODY' | jq . must succeed
- Match the expected schema: {"ip":"192.168.1.10","hostname":"printer","mac":"AA:BB:CC:DD:EE:FF"} with ip as string
- Ensure the Content-Type is application/json and the body is fully transmitted
- Check the server log line for the exact decode error (syntax error vs type mismatch) to pinpoint the field
Example fix
// before
curl -X POST .../control/dhcp/add_static_lease -d '{"ip": 3232235786, "mac":"AA:BB:CC:DD:EE:FF"}'
// -> 400 decoding json: json: cannot unmarshal number into Go struct field .ip of type string
// after
curl -X POST .../control/dhcp/add_static_lease -d '{"ip":"192.168.1.10","mac":"AA:BB:CC:DD:EE:FF"}' Defensive patterns
Strategy: validation
Validate before calling
var buf bytes.Buffer
_ = json.NewEncoder(&buf).Encode(lease)
if !json.Valid(buf.Bytes()) { /* fix payload before send */ } Try / catch
if err := addStaticLease(lease); err != nil {
if strings.Contains(err.Error(), "decoding json") {
// payload problem: re-validate body schema client-side (ip must be string)
}
} Prevention
- Always send ip/mac/hostname as JSON strings
- Marshal with a proper JSON encoder, don't hand-concatenate strings
- Echo the body through a JSON validator in scripts before POSTing
When it happens
Trigger: POSTing to add/remove/update static lease with body that is not valid JSON, has an unexpected field type, or an empty body; sending the IP as a JSON number instead of a string; missing Content-Length on a chunked truncated request.
Common situations: Hand-crafted curl requests with quoting mistakes; scripts written against an older API shape; proxies stripping or corrupting request bodies; passing a MAC with invalid characters in an unexpected field.
Related errors
- couldn't parse MAC address: %w
- parsing: %w
- subnet %s does not contain the ip %q
- found no dns servers in %s
- %v is not an IPv4 %s
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/de155d77f00d15d5.
Report an issue: GitHub.