AdguardTeam/AdGuardHome · warning

interface %s has no ipv6 addresses

Error message

interface %s has no ipv6 addresses

What it means

While parsing query-log search URL parameters, the filtering-status criterion received a value that is not in the allowed set (filteringStatusValues). Query log search accepts only specific status strings for the filtering criterion; anything else is rejected with 'invalid value <val>'.

Source

Thrown at internal/aghnet/dhcp_unix.go:230

		return true, false, nil
	}
}

// checkOtherDHCPv6 sends a DHCP request to the specified network interface, and
// waits for a response for a period defined by defaultDiscoverTime.  l must not
// be nil.
func checkOtherDHCPv6(
	ctx context.Context,
	l *slog.Logger,
	iface *net.Interface,
) (ok bool, err error) {
	ifaceIPNet, err := IfaceIPAddrs(iface, IPVersion6)
	if err != nil {
		return false, fmt.Errorf("getting ipv6 addrs for iface %s: %w", iface.Name, err)
	}
	if len(ifaceIPNet) == 0 {
		return false, fmt.Errorf("interface %s has no ipv6 addresses", iface.Name)
	}

	srcIP := ifaceIPNet[0]
	src := netutil.JoinHostPort(srcIP.String(), 546)
	dst := "[ff02::1:2]:547"

	udpAddr, err := net.ResolveUDPAddr("udp6", src)
	if err != nil {
		return false, fmt.Errorf("dhcpv6: Couldn't resolve UDP address %s: %w", src, err)
	}

	if !udpAddr.IP.To16().Equal(srcIP) {
		return false, fmt.Errorf("dhcpv6: Resolved UDP address is not %s: %w", src, err)
	}

	dstAddr, err := net.ResolveUDPAddr("udp6", dst)
	if err != nil {
		return false, fmt.Errorf("dhcpv6: Couldn't resolve UDP address %s: %w", dst, err)

View on GitHub (pinned to b41aefbe51)

Solutions

  1. Check the filteringStatusValues set in internal/querylog/http.go (or API docs) for accepted status strings
  2. Correct the value in the search expression and retry
  3. URL-encode the value properly if it contains special characters
  4. Pin/align client and server versions so status names match

Example fix

// before
GET /control/querylog?search=filtering_status(blocked_all)
// after
GET /control/querylog?search=filtering_status(blocked) // use an accepted value
Defensive patterns

Strategy: validation

Validate before calling

// Validate against known statuses before querying
var okStatuses = map[string]bool{"all": true, "filtered": true, "allowed": true, "blocked": true}
if !okStatuses[val] { return fmt.Errorf("bad status %q", val) }

Type guard

func isValidFilteringStatus(v string) bool {
    return filteringStatusValues[v] // mirror server set
}

Try / catch

if resp.StatusCode == 400 && strings.Contains(body, "invalid value") {
    // drop the bad criterion and retry with accepted statuses
}

Prevention

When it happens

Trigger: GET /control/querylog with a search parameter like search=filtering_status(X) where X is not one of the accepted filtering status values (e.g. all, filtered, allowed, blocked depending on the version).

Common situations: Client written against an older/newer API where status names changed; typos in the status value; assuming status names from filtering logs rather than query-log search vocabulary.

Related errors


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