OpenNHP/opennhp · error

failed to parse default route

Error message

failed to parse default route

What it means

getDefaultRouteInterface parses `ip route show default` output with the regex `default via (\S+) dev (\S+)` and returns "failed to parse default route" when fewer than 3 matches are found, i.e. the route table has no `default via X dev Y` line. EbpfEngineLoad depends on this to know which interface to attach the XDP program to.

Solutions

  1. Ensure the host has a standard default route: `ip route add default via <gw> dev eth0`
  2. Handle the via-less form by falling back to regex `default(?: via (\S+))? dev (\S+)` and reading the dev group
  3. Fall back to parsing /proc/net/route or `ip -j route show default` JSON when regex parsing fails
  4. Install iproute2 in minimal images and verify `ip route show default` manually

Example fix

// before
re := regexp.MustCompile(`default via (\S+) dev (\S+)`)
matches := re.FindStringSubmatch(string(output))
if len(matches) < 3 {
	return "", fmt.Errorf("failed to parse default route")
}
// after
re := regexp.MustCompile(`default(?: via (\S+))? dev (\S+)`)
matches := re.FindStringSubmatch(string(output))
if len(matches) < 3 {
	return "", fmt.Errorf("failed to parse default route from %q", string(output))
}
interfaceName := matches[2]
Defensive patterns

Strategy: fallback

Validate before calling

out, err := exec.Command("ip", "route", "show", "default").Output()
if err != nil || len(out) == 0 {
	return fmt.Errorf("no default route: ip output empty (install iproute2?)")
}

Try / catch

iface, err := getDefaultRouteInterface()
if err != nil {
	iface = os.Getenv("NHP_XDP_IFACE") // manual override
	if iface == "" { return err }
}

Prevention

When it happens

Trigger: `ip route show default` returns empty or unexpected output: no default route configured, a default route without a 'via' hop (point-to-point/on-link), localized/modified iproute2 output, or the `ip` binary is missing (command output empty).

Common situations: EC2/containers with only a link-scoped default route (`default dev eth0`); minimal container images without iproute2; hosts using multiple default routes or networkmanager custom formatting.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at endpoints/ac/ebpf/ebpfegine.go:287

		ip&0xFF,
		(ip>>8)&0xFF,
		(ip>>16)&0xFF,
		(ip>>24)&0xFF)
}

func getDefaultRouteInterface() (string, error) {
	cmd := exec.Command("ip", "route")
	output, err := cmd.Output()
	if err != nil {
		log.Error("failed to get running ip route:")
		return "", err
	}

	re := regexp.MustCompile(`default via (\S+) dev (\S+)`)
	matches := re.FindStringSubmatch(string(output))
	if len(matches) < 3 {
		log.Error("failed to parse default route")
		return "", fmt.Errorf("failed to parse default route")
	}
	interfaceName := matches[2]
	return interfaceName, nil
}

// clean eBPF map file
func CleanupBPFFiles() {
	bpfFiles := []string{
		"/sys/fs/bpf/xdp_white_prog",
		"/sys/fs/bpf/conn_track",
		"/sys/fs/bpf/icmpwhitelist",
		"/sys/fs/bpf/port_list",
		"/sys/fs/bpf/protocol_port",
		"/sys/fs/bpf/sdwhitelist",
		"/sys/fs/bpf/src_port",
		"/sys/fs/bpf/spp",
		"/sys/fs/bpf/tc_egress_prog",
	}

View on GitHub (pinned to 6e04ca5ff0)