cilium/cilium · error

interface %q: peer count mismatch (%s=%d, %s=%d)

Error message

interface %q: peer count mismatch (%s=%d, %s=%d)

What it means

compareIfaces in validateWireguardStates matches interfaces by name across the agent-reported and kernel-read WireGuard status, then compares fields. This error is joined when both sides report the same interface but with a different PeerCount, i.e. the agent believes a different number of public keys/peers are attached to the device than the kernel actually has.

Source

Thrown at cilium-dbg/cmd/encrypt_status.go:134

		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))
			}
		}
	}

	if len(agent.Interfaces) != len(kernel.Interfaces) {
		errs = errors.Join(errs, fmt.Errorf("interface count mismatch (agent=%d, kernel=%d)",
			len(agent.Interfaces), len(kernel.Interfaces)))
	}

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Inspect the actual peer list (`wg show cilium_wg0`) versus agent logs to identify which peer is missing/extra; restart the agent to force peer re-derivation from cluster state.
  2. Check agent logs for WireGuard peer reconciliation errors and fix the underlying cause (e.g. node public key rotation failures) before restarting.
  3. If keys were rotated externally, restart the agent so it re-programs the correct peer set on the kernel device.
  4. Upgrade mismatched Cilium versions in the cluster so agent and datapath conventions match.

Example fix

// before
Msg: ... interface "cilium_wg0": peer count mismatch (agent=5, kernel=4)
// after: restart agent to reconcile peers
$ kubectl -n kube-system rollout restart daemonset/cilium
$ wg show cilium_wg0 peers | wc -l
Defensive patterns

Strategy: validation

Validate before calling

// Compare peer counts on both sides before trusting the state
wgOut, _ := exec.Command("wg", "show", "cilium_wg0", "peers").Output()
kernelPeers := len(strings.Fields(string(wgOut)))
for _, i := range agent.Interfaces {
    if i.Name == "cilium_wg0" && int(i.PeerCount) != kernelPeers {
        fmt.Println("agent peer count out of sync with kernel; restart agent")
    }
}

Type guard

func peerCountMatches(a, k *models.WireguardInterface) bool {
    return a != nil && k != nil && a.PeerCount == k.PeerCount
}

Try / catch

if err := validateWireguardStates(agent, kernel); err != nil {
    if strings.Contains(err.Error(), "peer count mismatch") {
        // reconcile: restart agent to re-derive peers from cluster state
    }
}

Prevention

When it happens

Trigger: `cilium encrypt status` in wireguard mode where models.WireguardInterface.PeerCount for the same-named interface differs between agent healthz payload and wgctrl device dump — typically when a peer is (or was just) added/removed and the agent's view is out of sync with the live kernel device.

Common situations: Node peer configuration changed (node added/removed from cluster) and the agent is mid-update or stuck; failed peer reconciliation after Cilium config change; stale agent healthz data after the interface was re-keyed externally with `wg` or `wg-quick`; version skew between agent components.

Related errors


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