AdguardTeam/AdGuardHome · error
start is greater than or equal to end
Error message
start is greater than or equal to end
What it means
Returned by newIPRange when the DHCP range's start address is greater than or equal to its end address (compared as big-endian byte slices converted to big.Int). A valid range must be strictly increasing. This surfaces either directly from range validation or wrapped as 'bad dhcpv4/dhcpv6 configuration' from the HTTP API.
Source
Thrown at internal/dhcpd/iprange.go:44
// maxRangeLen is the maximum IP range length. The bitsets used in servers only
// accept uints, which can have the size of 32 bit.
const maxRangeLen = math.MaxUint32
// newIPRange creates a new IP address range. start must be less than end. The
// resulting range must not be greater than maxRangeLen.
func newIPRange(start, end net.IP) (r *ipRange, err error) {
defer func() { err = errors.Annotate(err, "invalid ip range: %w") }()
// Make sure that both are 16 bytes long to simplify handling in
// methods.
start, end = start.To16(), end.To16()
startInt := (&big.Int{}).SetBytes(start)
endInt := (&big.Int{}).SetBytes(end)
diff := (&big.Int{}).Sub(endInt, startInt)
if diff.Sign() <= 0 {
return nil, fmt.Errorf("start is greater than or equal to end")
} else if !diff.IsUint64() || diff.Uint64() > maxRangeLen {
return nil, fmt.Errorf("range is too large")
}
r = &ipRange{
start: startInt,
end: endInt,
}
return r, nil
}
// contains returns true if r contains ip.
func (r *ipRange) contains(ip net.IP) (ok bool) {
if r == nil {
return false
}
View on GitHub (pinned to b41aefbe51)
Solutions
- Swap the values so start < end (compare octet by octet or with python3 -c 'import ipaddress; print(ipaddress.IPv4Address(a) < ipaddress.IPv4Address(b))')
- Add client-side validation before submitting the config
- For IPv6 /64 ranges, verify only host bits differ and start's host bits are lower
Example fix
// before "range_start":"192.168.1.200","range_end":"192.168.1.100" // -> start is greater than or equal to end // after "range_start":"192.168.1.100","range_end":"192.168.1.200"
Defensive patterns
Strategy: validation
Validate before calling
func rangeOrdered(start, end string) bool {
s, e := net.ParseIP(start), net.ParseIP(end)
return s != nil && e != nil && bytes.Compare(s.To16(), e.To16()) < 0
} Prevention
- Always validate start < end client-side before submitting
- Compare with ipaddress (Python) or net.ParseIP byte comparison, not string compare
- Watch for transposed octets when hand-editing configs
When it happens
Trigger: Setting range_start >= range_end in a DHCPv4 or DHCPv6 config; transposing octets (192.168.1.200 as start, 192.168.1.100 as end); DHCPv6 pairs where the low 64 bits of start exceed those of end.
Common situations: Transposed octets when hand-editing YAML/JSON configs; misunderstanding that end is exclusive-of-equal; migrating a config where start/end fields got swapped; unit tests feeding reversed pairs.
Related errors
- range is too large
- gateway ip %v in the ip range: %v-%v
- bad dhcpv4 configuration: %w
- bad dhcpv6 configuration: %w
- dhcpv4 or dhcpv6 configuration must be complete
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/cb7cec0a0fe37823.
Report an issue: GitHub.