cilium/cilium · error
detected duplicate public key. node %q uses same key as exis
Error message
detected duplicate public key. node %q uses same key as existing node %q
What it means
The agent maintains a map from public keys to node names; updatePeer rejects a public key that is already registered to a different node. This prevents two nodes from presenting the same identity, which would break peer routing. Usually indicates cloned nodes or leaked stale state.
Source
Thrown at pkg/wireguard/agent/agent.go:537
a.Lock()
defer a.Unlock()
if a.wgClient == nil {
return nil
}
pubKey, err := wgtypes.ParseKey(pubKeyHex)
if err != nil {
return err
}
if pubKey == wgDummyPeerKey {
return fmt.Errorf("node %q is not allowed to use the dummy peer key", nodeName)
}
if prevNodeName, ok := a.nodeNameByPubKey[pubKey]; ok {
if nodeName != prevNodeName {
return fmt.Errorf("detected duplicate public key. "+
"node %q uses same key as existing node %q", nodeName, prevNodeName)
}
}
peer := a.peerByNodeName[nodeName]
// Reinitialize peer if its public key changed.
if peer != nil && peer.pubKey != pubKey {
a.logger.Debug(
"Pubkey has changed",
logfields.NodeName, nodeName,
)
if err := a.deletePeerByPubKey(peer.pubKey); err != nil {
return err
}
peer = nil
}
View on GitHub (pinned to ac7b90affa)
Solutions
- Delete the stale private key file (/var/lib/cilium/wg or configured path) on the cloned node and restart the agent to regenerate keys
- Ensure the node's identity (name) is stable; fix hostname/K8s node name mismatches
- Remove the stale CiliumNode resource for the old node name
- If intentional key rotation, remove the old peer mapping first
Example fix
// on the cloned node // before rm /var/lib/cilium/wg # (stop cilium-agent first) // after systemctl restart cilium-agent # generates a fresh key pair
Defensive patterns
Strategy: validation
Validate before calling
func ensureUniqueKey(keyHex, nodeName string, keyToNode map[string]string) error {
if owner, ok := keyToNode[keyHex]; ok && owner != nodeName {
return fmt.Errorf("key already owned by node %q", owner)
}
return nil
} Try / catch
if err := updatePeer(nodeName, key); err != nil {
if strings.Contains(err.Error(), "duplicate public key") {
// clone detected: force key regeneration on the node
}
} Prevention
- Never clone nodes/VMs with an existing /var/lib/cilium/wg private key
- Wipe the WireGuard key file when baking node images
- Use stable, unique node names
- Delete stale CiliumNode resources during node replacement
When it happens
Trigger: Update is called for node B with a public key already mapped to node A in nodeNameByPubKey, e.g. a VM cloned with its /var/lib/cilium/wg private key intact.
Common situations: Node images/VMs cloned without regenerating the WireGuard private key, restoring a node from a snapshot, or DNS/hostname changes making the same node appear under a new name with its old key.
Related errors
- %w: both agent and kernel states are empty
- %w: agent state is empty
- %w: kernel state is empty
- interface %q exists in %s but is missing in %s
- interface %q: peer count mismatch (%s=%d, %s=%d)
AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31).
Data as JSON: /api/errors/46c697cd3c18e9c7.
Report an issue: GitHub.