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

  1. Validate the JSON before sending: echo '$BODY' | jq . must succeed
  2. Match the expected schema: {"ip":"192.168.1.10","hostname":"printer","mac":"AA:BB:CC:DD:EE:FF"} with ip as string
  3. Ensure the Content-Type is application/json and the body is fully transmitted
  4. 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

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


AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27). Data as JSON: /api/errors/de155d77f00d15d5. Report an issue: GitHub.