AdguardTeam/AdGuardHome · error
decoding dur: %w
Error message
decoding dur: %w
What it means
Returned by parseDHCPOptionDur when a DHCP option typed as duration fails timeutil.Duration.UnmarshalText. Accepts human-readable forms like '1h30m' or Go duration syntax, and rejects plain numbers without units (unless a unit is implied by the specific format) and garbage strings.
Source
Thrown at internal/dhcpd/options_unix.go:84
for i, ipStr := range strings.Split(s, ",") {
ip, err = parseDHCPOptionIP(ipStr)
if err != nil {
return nil, fmt.Errorf("parsing ip at index %d: %w", i, err)
}
ips = append(ips, net.IP(ip.(dhcpv4.IP)))
}
return ips, nil
}
// parseDHCPOptionDur parses a DHCP option as a duration in a human-readable
// form.
func parseDHCPOptionDur(s string) (val dhcpv4.OptionValue, err error) {
var v timeutil.Duration
err = v.UnmarshalText([]byte(s))
if err != nil {
return nil, fmt.Errorf("decoding dur: %w", err)
}
return dhcpv4.Duration(v), nil
}
// parseDHCPOptionUint parses a DHCP option as an unsigned integer. bitSize is
// expected to be 8 or 16.
func parseDHCPOptionUint(s string, bitSize int) (val dhcpv4.OptionValue, err error) {
var v uint64
v, err = strconv.ParseUint(s, 10, bitSize)
if err != nil {
return nil, fmt.Errorf("decoding u%d: %w", bitSize, err)
}
switch bitSize {
case 8:
return dhcpv4.OptionGeneric{Data: []byte{uint8(v)}}, nil
case 16:View on GitHub (pinned to b41aefbe51)
Solutions
- Use Go-style duration strings with explicit units: '3600s', '1h', '1h30m'
- Spell units exactly (s, m, h, d where supported) without spaces between number and unit
- Test parseability locally: go run - <<<'package main;import("fmt";"time");func main(){_,e:=time.ParseDuration("1h");fmt.Println(e)}'
Example fix
// before "value":"3600" // -> decoding dur: time: invalid duration "3600" (missing unit) // after "value":"3600s"
Defensive patterns
Strategy: validation
Validate before calling
func durOK(s string) bool {
_, err := time.ParseDuration(s) // close proxy for timeutil.Duration
return err == nil
} Prevention
- Always attach a unit: '3600s' not '3600'
- Use Go duration syntax (h, m, s)
- Test-parse durations in your config pipeline
When it happens
Trigger: Setting an option (e.g. lease time or renew timers) with value '3600' instead of '1h' or '3600s', or with typos like '1hr', '30seconds'.
Common situations: Assuming seconds as a raw number is accepted; copying '1h' vs '1 h' spacing differences; vendor docs quoting lease times in bare seconds.
Related errors
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/ad4b84130a893d75.
Report an issue: GitHub.