AdguardTeam/AdGuardHome · warning
invalid ip version %d
Error message
invalid ip version %d
What it means
The query-log search parser encountered a criterion type that is not one of ctTerm, ctFilteringStatus, or ctReason. The parser dispatches on the criterion prefix inside the search expression; an unrecognized prefix/type falls through to this default case listing the valid types.
Source
Thrown at internal/aghnet/interfaces.go:32
// IP version constants.
const (
IPVersion4 IPVersion = 4
IPVersion6 IPVersion = 6
)
// NetIface is the interface for network interface methods.
type NetIface interface {
Addrs() ([]net.Addr, error)
}
// IfaceIPAddrs returns the interface's IP addresses. iface must not be nil.
func IfaceIPAddrs(iface NetIface, ipv IPVersion) (ips []net.IP, err error) {
switch ipv {
case IPVersion4, IPVersion6:
// Go on.
default:
return nil, fmt.Errorf("invalid ip version %d", ipv)
}
addrs, err := iface.Addrs()
if err != nil {
return nil, err
}
for _, a := range addrs {
if ip := ipFromAddr(a, ipv); ip != nil {
ips = append(ips, ip)
}
}
return ips, nil
}
// ipFromAddr converts addr to IP. addr must not be nil.
func ipFromAddr(addr net.Addr, ipv IPVersion) (ip net.IP) {View on GitHub (pinned to b41aefbe51)
Solutions
- Rewrite the search using only term, filtering_status, and reason criteria
- Escape or remove parentheses in plain-text search terms
- Upgrade the server if the client legitimately needs a newer criterion type
- Inspect parseSearchCriterion's dispatch to see exact recognized prefixes
Example fix
// before GET /control/querylog?search=device(laptop) // after GET /control/querylog?search=laptop
Defensive patterns
Strategy: validation
Validate before calling
var validTypes = map[string]bool{"term": true, "filtering_status": true, "reason": true}
if !validTypes[critType] { skip() } Type guard
func isValidCriterion(c string) bool {
t := c[:strings.IndexByte(c, '(')]
return t == "" || validTypes[t]
} Try / catch
if resp.StatusCode == 400 && strings.Contains(body, "invalid criterion type") {
// rewrite query using plain terms only
} Prevention
- Escape parentheses in free-text terms
- Keep search syntax in a shared client module
- Version-gate new criterion types against server capabilities
When it happens
Trigger: GET /control/querylog?search=... where the search expression contains a criterion whose type (text before the parentheses) is not term/filtering_status/reason, e.g. search=client(x) or a stray 'name(' in the expression.
Common situations: Copy-pasting search syntax from a different product or older version; unescaped parentheses in a free-text term being parsed as a criterion; client sending a new criterion type to an older server.
Related errors
- interface %s has no ipv6 addresses
- could not find hardware port for %s
- json time is nil
- networksetup failed to set dns servers: %w
- parsing etc/resolv.conf file: %w
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/c1953165254cd3a5.
Report an issue: GitHub.