AdguardTeam/AdGuardHome · warning
could not find hardware port for %s
Error message
could not find hardware port for %s
What it means
parseReason iterates over every value of a reason search criterion and rejects any name not present in filtering.ReasonByName. Each bad value produces an error wrapping errors.ErrBadEnumValue with the offending string; the errors are aggregated and returned.
Source
Thrown at internal/aghnet/net_darwin.go:59
if err != nil {
return false, err
}
return portInfo.static, nil
}
// getCurrentHardwarePortInfo returns information for the specified network
// interface. cmdCons must not be nil.
func getCurrentHardwarePortInfo(
ctx context.Context,
cmdCons executil.CommandConstructor,
ifaceName string,
) (hardwarePortInfo, error) {
// First, find the hardware port name.
m := getNetworkSetupHardwareReports(ctx, cmdCons)
hardwarePort, ok := m[ifaceName]
if !ok {
return hardwarePortInfo{}, fmt.Errorf("could not find hardware port for %s", ifaceName)
}
return getHardwarePortInfo(ctx, cmdCons, hardwarePort)
}
// hardwareReportsReg is the regular expression matching the lines of
// networksetup command output lines containing the interface information.
var hardwareReportsReg = regexp.MustCompile("Hardware Port: (.*?)\nDevice: (.*?)\n")
// getNetworkSetupHardwareReports returns a map of interface names to hardware
// port names. It returns nil if parsing fails. cmdCons must not be nil.
//
// TODO(e.burkov): There should be more proper approach than parsing the
// command output. For example, see
// https://developer.apple.com/documentation/systemconfiguration.
func getNetworkSetupHardwareReports(
ctx context.Context,
cmdCons executil.CommandConstructor,View on GitHub (pinned to b41aefbe51)
Solutions
- Use only reason names registered in filtering.ReasonByName (check the filtering package or API docs)
- Fix typos in the reason value and retry
- Upgrade server/client to matching versions if the reason was added recently
Example fix
// before GET /control/querylog?search=reason(FilteredUnknown) // after GET /control/querylog?search=reason(FilteredBlackList) // a registered reason name
Defensive patterns
Strategy: validation
Validate before calling
if _, ok := filtering.ReasonByName[val]; !ok { return fmt.Errorf("unknown reason %q", val) } Type guard
func isKnownReason(name string) bool {
_, ok := filtering.ReasonByName[name]
return ok
} Try / catch
if resp.StatusCode == 400 && strings.Contains(body, errors.ErrBadEnumValue.Error()) {
// filter out unknown reasons and retry
} Prevention
- Use reason names exported by the filtering package
- Avoid hardcoding reason strings; derive from the API
- Upgrade client and server together
When it happens
Trigger: GET /control/querylog with search=reason(...) where any value inside the parentheses is not a registered filtering reason name (e.g. a typo or a reason only produced by a different version).
Common situations: Listing reason names from filtering logs of a newer version against an older server; typos; mixing up filtering status names with reason names.
Related errors
- interface %s has no ipv6 addresses
- invalid ip version %d
- networksetup failed to set dns servers: %w
- parsing etc/resolv.conf file: %w
- json time is nil
AI-assisted analysis of AdguardTeam/AdGuardHome@b41aefbe51 (2026-08-27).
Data as JSON: /api/errors/0ab206eb65ee2758.
Report an issue: GitHub.