cilium/cilium · error
interface %q exists in %s but is missing in %s
Error message
interface %q exists in %s but is missing in %s
What it means
Inside validateWireguardStates, compareIfaces iterates each interface in the 'from' list (agent or kernel) and looks up the same-named interface in the 'to' list via findIface. When a WireGuard interface is present on one side but no interface with that name exists on the other, this error is joined into the aggregate result. It indicates agent and kernel fundamentally disagree about which WireGuard devices exist.
Source
Thrown at cilium-dbg/cmd/encrypt_status.go:128
findIface := func(ifaces []*models.WireguardInterface, name string) *models.WireguardInterface {
for _, iface := range ifaces {
if iface.Name == name {
return iface
}
}
return nil
}
compareIfaces := func(from, to []*models.WireguardInterface, fromLabel, toLabel string) {
for _, f := range from {
if _, seen := seenIfaces[f.Name]; seen {
continue
}
seenIfaces[f.Name] = struct{}{}
t := findIface(to, f.Name)
if t == nil {
errs = errors.Join(errs, fmt.Errorf("interface %q exists in %s but is missing in %s",
f.Name, fromLabel, toLabel))
continue
}
if f.PeerCount != t.PeerCount {
errs = errors.Join(errs, fmt.Errorf("interface %q: peer count mismatch (%s=%d, %s=%d)",
f.Name, fromLabel, f.PeerCount, toLabel, t.PeerCount))
}
if f.ListenPort != t.ListenPort {
errs = errors.Join(errs, fmt.Errorf("interface %q: listen port mismatch (%s=%d, %s=%d)",
f.Name, fromLabel, f.ListenPort, toLabel, t.ListenPort))
}
if f.PublicKey != t.PublicKey {
errs = errors.Join(errs, fmt.Errorf("interface %q: public key mismatch (%s=%s, %s=%s)",
f.Name, fromLabel, f.PublicKey, toLabel, t.PublicKey))
}
}
}View on GitHub (pinned to ac7b90affa)
Solutions
- Compare reported names: run `cilium encrypt status` and `ip -d link show type wireguard` to see which side lists the interface; align by restarting the agent to re-sync its view with the kernel.
- If the kernel device is genuinely missing, restart the Cilium agent so it recreates cilium_wg0 and repopulates peers.
- If an unexpected/renamed device exists, check for config changes (encryption enabled/disabled flapping) and clean up stale interfaces manually (`ip link del <name>`) before restarting the agent.
- Run the CLI from the host network namespace as root so wgctrl can see all WireGuard devices.
Example fix
// before: agent knows cilium_wg0, kernel side absent Msg: wireguard state mismatch...: interface "cilium_wg0" exists in agent but is missing in kernel // after: restart agent to recreate the device $ kubectl -n kube-system rollout restart daemonset/cilium $ cilium encrypt status # Msg line gone
Defensive patterns
Strategy: validation
Validate before calling
// Pre-check that the interface sets match before detailed comparison
agentNames := map[string]bool{}
for _, i := range agent.Interfaces { agentNames[i.Name] = true }
kernelNames := map[string]bool{}
for _, i := range kernel.Interfaces { kernelNames[i.Name] = true }
for n := range agentNames { if !kernelNames[n] { fmt.Printf("%s missing on kernel side\n", n) } } Type guard
func ifacePresent(ifaces []*models.WireguardInterface, name string) *models.WireguardInterface {
for _, i := range ifaces {
if i.Name == name { return i }
}
return nil
} Try / catch
if err := validateWireguardStates(agent, kernel); err != nil {
if strings.Contains(err.Error(), "exists in") {
// interface-set divergence: trigger agent restart/re-sync
}
} Prevention
- Avoid manually deleting or renaming cilium_wg0 while the agent is running.
- Keep all nodes on the same Cilium version to avoid interface naming differences.
- Run the CLI in the host network namespace so the kernel-side dump is complete.
- After enabling WireGuard mode, confirm the device appears with `ip -d link show type wireguard`.
When it happens
Trigger: `cilium encrypt status` in wireguard mode where the agent's healthz Wireguard.Interfaces list and the kernel dump (dumpWireGuardStatus, which reports only the cilium_wg0 device) do not share an interface name — e.g. agent reports cilium_wg0 but the kernel device is absent, or named differently.
Common situations: Agent recreated the interface with a different name after a config change; leftover/stale agent state after interface deletion; the CLI runs in a namespace where the kernel device is not visible so the kernel side list is empty; partial rollout where some nodes run different Cilium versions with different interface naming.
Related errors
- %w: kernel state is empty
- interface %q: peer count mismatch (%s=%d, %s=%d)
- interface %q: listen port mismatch (%s=%d, %s=%d)
- interface %q: public key mismatch (%s=%s, %s=%s)
- failed to unmarshal bgp state from %s: %w
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/a832fbd1180d0789.
Report an issue: GitHub.