AdguardTeam/AdGuardHome · error

bad dhcpv4 configuration: %w

Error message

bad dhcpv4 configuration: %w

What it means

Raised inside createServers when the DHCPv4 portion of the submitted configuration is invalid. handleDHCPSetConfigV4 validates fields such as the IPv4 range (start/end), gateway, subnet mask, and lease duration; any failure is wrapped as 'bad dhcpv4 configuration'. The HTTP request is rejected before any server is started.

Source

Thrown at internal/dhcpd/http_unix.go:301

	v6Conf.RASLAACOnly = s.conf.Conf6.RASLAACOnly
	v6Conf.RAAllowSLAAC = s.conf.Conf6.RAAllowSLAAC

	enabled = v6Conf.Enabled
	v6Conf.InterfaceName = conf.InterfaceName
	v6Conf.Logger = s.conf.Logger.With("ip_version", "6")
	v6Conf.notify = s.onNotify

	srv6, err = v6Create(v6Conf)

	return srv6, enabled, err
}

// createServers returns DHCPv4 and DHCPv6 servers created from the provided
// configuration conf.
func (s *server) createServers(conf *dhcpServerConfigJSON) (srv4, srv6 DHCPServer, err error) {
	srv4, v4Enabled, err := s.handleDHCPSetConfigV4(conf)
	if err != nil {
		return nil, nil, fmt.Errorf("bad dhcpv4 configuration: %w", err)
	}

	srv6, v6Enabled, err := s.handleDHCPSetConfigV6(conf)
	if err != nil {
		return nil, nil, fmt.Errorf("bad dhcpv6 configuration: %w", err)
	}

	if conf.Enabled == aghalg.NBTrue && !v4Enabled && !v6Enabled {
		return nil, nil, fmt.Errorf("dhcpv4 or dhcpv6 configuration must be complete")
	}

	return srv4, srv6, nil
}

// handleDHCPSetConfig is the handler for the POST /control/dhcp/set_config
// HTTP API.
func (s *server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Check range_start is strictly less than range_end and both are valid IPv4 addresses
  2. Ensure the range lies within the configured subnet and is not larger than the max range length
  3. Validate gateway, subnet_mask, and all IP fields parse as dotted-quad IPv4
  4. Correct the JSON payload and re-POST; use GET /control/dhcp/status first to inspect current values

Example fix

// before
{"enabled":true,"v4":{"range_start":"192.168.1.100","range_end":"192.168.1.50",...}}
// -> 400 bad dhcpv4 configuration: start is greater than or equal to end

// after
{"enabled":true,"v4":{"range_start":"192.168.1.50","range_end":"192.168.1.100",...}}
Defensive patterns

Strategy: validation

Validate before calling

func validV4Range(start, end string) bool {
	s := net.ParseIP(start).To4(); e := net.ParseIP(end).To4()
	return s != nil && e != nil && binary.BigEndian.Uint32(s) < binary.BigEndian.Uint32(e)
}

Try / catch

if err := setDHCPConfig(cfg); err != nil {
    if strings.HasPrefix(err.Error(), "bad dhcpv4 configuration") { /* inspect cfg.V4 fields */ }
}

Prevention

When it happens

Trigger: POSTing dhcp/set_config with an invalid IPv4 block: range_start >= range_end, range outside the subnet, a malformed gateway/subnet_mask IP, or a range that exceeds the maximum allowed size.

Common situations: Typos in range_start/range_end (transposed octets), using /8-sized subnets that blow the max range length, entering a DNS server or gateway that is not a valid IPv4 address, or copying a config between machines with different subnets.

Related errors


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