cilium/cilium · error

failed to get host device %s

Error message

failed to get host device %s

What it means

When routing from-proxy routes are required (native routing with Envoy L7 proxy, IPSec, or WireGuard) and IPv4 is enabled, ReinstallRoutingRules requires the host device (defaults.HostDevice, e.g. cilium_host) from the device table. If that lookup fails it returns this error because the from-proxy default route and link route need the host device as their output device.

Source

Thrown at pkg/proxy/routes.go:65

	fromIngressProxy, fromEgressProxy, mtu := requireFromProxyRoutes(ipsecEnabled, wireguardEnabled, mtu)

	rxn := p.db.ReadTxn()
	hostDevice, _, hostDeviceFound := p.devices.Get(rxn, tables.DeviceByName(defaults.HostDevice))
	ciliumNetDevice, _, ciliumNetDeviceFound := p.devices.Get(rxn, tables.DeviceByName(defaults.SecondHostDevice))
	lo, _, loFound := p.devices.Get(rxn, tables.DeviceByName("lo"))

	if option.Config.EnableIPv4 && p.enabled {
		if !loFound {
			return fmt.Errorf("failed to get loopback device")
		}
		if err := installToProxyRoutesIPv4(lo, p.routeManager, p.routeOwner); err != nil {
			return err
		}

		if fromIngressProxy || fromEgressProxy {
			if !hostDeviceFound {
				return fmt.Errorf("failed to get host device %s", defaults.HostDevice)
			}
			internalIP, _ := netipx.FromStdIP(localNode.GetCiliumInternalIP(false))
			if err := installFromProxyRoutesIPv4(p.routeManager, p.routeOwner, internalIP, hostDevice, fromIngressProxy, fromEgressProxy, mtu); err != nil {
				return err
			}
		} else {
			if err := removeFromProxyRulesIPv4(); err != nil {
				return err
			}
		}
	} else {
		if err := removeToProxyRulesIPv4(); err != nil {
			return err
		}
		if err := removeFromProxyRulesIPv4(); err != nil {
			return err
		}
	}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Ensure node initialization has completed so cilium_host exists and is registered in the devices table before ReinstallRoutingRules runs.
  2. Verify `ip link show cilium_host` succeeds on the node; if missing, restart the agent to recreate it.
  3. Retry the reinitialize loop — the device is typically registered shortly after startup.
  4. Check that no custom device filtering excludes cilium_host from the devices table.

Example fix

// before
if !hostDeviceFound {
    return fmt.Errorf("failed to get host device %s", defaults.HostDevice)
}
// after
// retry with backoff until the device table contains cilium_host
hostDevice, _, hostDeviceFound := p.devices.Get(rxn, tables.DeviceByName(defaults.HostDevice))
if !hostDeviceFound {
    return retry.NewError(ctx, true, fmt.Errorf("failed to get host device %s", defaults.HostDevice))
}
Defensive patterns

Strategy: retry

Validate before calling

rxn := p.db.ReadTxn()
if _, _, ok := p.devices.Get(rxn, tables.DeviceByName(defaults.HostDevice)); !ok {
    return fmt.Errorf("host device %s not registered yet", defaults.HostDevice)
}

Type guard

func hostDeviceReady(devs deviceCache) bool {
    _, _, ok := devs.Get(devs.ReadTxn(), tables.DeviceByName(defaults.HostDevice))
    return ok
}

Try / catch

if err := p.ReinstallRoutingRules(ctx, mtu, ipsec, wg); err != nil {
    if strings.Contains(err.Error(), "failed to get host device") {
        return retry.NewError(ctx, true, err) // retriable until cilium_host exists
    }
    return err
}

Prevention

When it happens

Trigger: Calling ReinstallRoutingRules with EnableIPv4=true, proxy enabled, and fromIngressProxy/fromEgressProxy true (EnableEnvoyConfig, ipsecEnabled, or wireguardEnabled) while p.devices has no entry for defaults.HostDevice.

Common situations: cilium_host interface not yet created during early agent startup; node initialization failure left the host device unregistered; environment where the cilium_host link was deleted manually; device table not synced with netlink.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/6837328522e4e01f. Report an issue: GitHub.