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
- 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.
- Check agent logs for WireGuard peer reconciliation errors and fix the underlying cause (e.g. node public key rotation failures) before restarting.
- If keys were rotated externally, restart the agent so it re-programs the correct peer set on the kernel device.
- 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
- Let Cilium manage all WireGuard peers; never modify peers with `wg set` directly.
- Watch agent logs for peer reconciliation errors after node add/remove events.
- Re-run `cilium encrypt status` after cluster topology changes to catch drift early.
- Avoid interrupting agent restarts mid key/peer programming.
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
- %w: kernel state is empty
- interface %q exists in %s but is missing in %s
- 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/e4b06ca4013b8a9e.
Report an issue: GitHub.