OpenNHP/opennhp · error

only IPv4 addresses are supported

Error message

only IPv4 addresses are supported: %s

What it means

After net.ParseIP succeeds, parseIP converts to 4-byte form with ip.To4(). IPv6 addresses (and any value that is not IPv4) yield nil from To4, so the function rejects them because the eBPF rule maps store 32-bit IPv4 keys only. The address must be a literal IPv4 address.

Solutions

  1. Supply a literal IPv4 address instead of IPv6
  2. If dual-stack is required, extend the eBPF map/key structs to v6 or maintain a separate v4/v6 rule path
  3. Pre-validate with `ip := net.ParseIP(s); ip.To4() != nil` and surface a clear config error

Example fix

// before
AddEbpfRuleForSrcDst("::1", "10.0.0.1", ...)
// after
AddEbpfRuleForSrcDst("127.0.0.1", "10.0.0.1", ...)
Defensive patterns

Strategy: validation

Validate before calling

func isIPv4(s string) bool { ip := net.ParseIP(s); return ip != nil && ip.To4() != nil }

Try / catch

if err := addRule(...); err != nil { if strings.Contains(err.Error(), "only IPv4") { /* convert or skip */ } }

Prevention

When it happens

Trigger: Passing an IPv6 literal like '::1' or '2001:db8::1' (or an IPv4-mapped form that the map format cannot accept) to any of the AddEbpf* rule functions; passing a hostname that ParseIP resolves as IPv6 only.

Common situations: Dual-stack environments where configured endpoints have AAAA records; users copying IPv6 addresses from `ip -6` output; configs written for IPv6-only clusters.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07). Data as JSON: /api/errors/667f1c43747dd806. Report an issue: GitHub.

Appendix: source

Thrown at nhp/utils/ebpf/ebpf.go:475

	default:
		return fmt.Errorf("unsupported map type: %d", mapType)
	}

	return nil
}

// Parse the IP address
func parseIP(ipStr string) (uint32, error) {
	ip := net.ParseIP(ipStr)
	if ip == nil {
		log.Error("invalid IP address: %s", ipStr)
		return 0, fmt.Errorf("invalid IP address: %s", ipStr)
	}
	ip = ip.To4()
	if ip == nil {
		log.Error("only IPv4 addresses are supported: %s", ipStr)
		return 0, fmt.Errorf("only IPv4 addresses are supported: %s", ipStr)
	}
	return binary.LittleEndian.Uint32(ip), nil
}

// Parse the port
func parsePort(portStr string) (uint16, error) {
	port, err := strconv.ParseUint(portStr, 10, 16)
	if err != nil {
		return 0, err
	}
	return binary.LittleEndian.Uint16([]byte{byte(port >> 8), byte(port & 0xFF)}), nil
}

View on GitHub (pinned to 6e04ca5ff0)