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

  1. Swap the values so start < end (compare octet by octet or with python3 -c 'import ipaddress; print(ipaddress.IPv4Address(a) < ipaddress.IPv4Address(b))')
  2. Add client-side validation before submitting the config
  3. 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

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


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