AdguardTeam/AdGuardHome · error

lease %s (%s) out of range, not adding

Error message

lease %s (%s) out of range, not adding

What it means

addLease rejects a dynamic lease whose IP is not within the server's dynamic address offset range (the pool between the configured offset start and end). Dynamic (non-static) leases must fall inside the allocatable pool; otherwise they are considered out of range and refused.

Source

Thrown at internal/dhcpd/v4_unix.go:329

	}

	return nil
}

// addLease adds a dynamic or static lease.
func (s *v4Server) addLease(l *dhcpsvc.Lease) (err error) {
	r := s.conf.ipRange
	leaseIP := net.IP(l.IP.AsSlice())
	offset, inOffset := r.offset(leaseIP)

	if l.IsStatic {
		// TODO(a.garipov, d.seregin): Subnet can be nil when dhcp server is
		// disabled.
		if sn := s.conf.subnet; !sn.Contains(l.IP) {
			return fmt.Errorf("subnet %s does not contain the ip %q", sn, l.IP)
		}
	} else if !inOffset {
		return fmt.Errorf("lease %s (%s) out of range, not adding", l.IP, l.HWAddr)
	}

	// TODO(e.burkov):  l must have a valid hostname here, investigate.
	if l.Hostname != "" {
		if _, ok := s.hostsIndex[l.Hostname]; ok {
			return fmt.Errorf("hostname: %w", errors.ErrDuplicated)
		}

		s.hostsIndex[l.Hostname] = l
	}
	s.ipIndex[l.IP] = l

	s.leases = append(s.leases, l)
	s.leasedOffsets.set(offset, true)

	return nil
}

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Widen the DHCP range back to cover the stored leases
  2. Clear/reset the leases table so stale out-of-range leases are dropped
  3. Reconcile the lease store whenever the DHCP range configuration changes

Example fix

// before
range_start: 192.168.1.100
range_end: 192.168.1.120 // leases at .150 now out of range

// after
range_end: 192.168.1.200 // or clear stored leases
Defensive patterns

Strategy: validation

Validate before calling

// check pool membership before persisting dynamic leases
offset, ok := r.offset(leaseIP)
if !ok { /* drop the stale lease instead of re-adding */ }

Try / catch

// ignore out-of-range errors when resetting leases
everythingElse, _ := srv.ResetLeases(leases) // or filter leases first

Prevention

When it happens

Trigger: ResetLeases, reserveLease, or handleDecline tries to add a dynamic lease with an IP outside the configured offset range — typically after shrinking the DHCP range while persisted leases still reference old IPs.

Common situations: Shrinking the DHCP pool range while the lease database still contains leases in the removed range; restoring a lease dump onto a server with a different/smaller range; race where the range changed after the IP was picked.

Related errors


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