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

  1. Use only reason names registered in filtering.ReasonByName (check the filtering package or API docs)
  2. Fix typos in the reason value and retry
  3. 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

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


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