{"record":{"id":"46c697cd3c18e9c7","repo":"cilium/cilium","slug":"detected-duplicate-public-key-node-q-uses-same-k","errorCode":null,"errorMessage":"detected duplicate public key. node %q uses same key as existing node %q","messagePattern":"detected duplicate public key\\. node %q uses same key as existing node %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/wireguard/agent/agent.go","lineNumber":537,"sourceCode":"\n\ta.Lock()\n\tdefer a.Unlock()\n\tif a.wgClient == nil {\n\t\treturn nil\n\t}\n\n\tpubKey, err := wgtypes.ParseKey(pubKeyHex)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif pubKey == wgDummyPeerKey {\n\t\treturn fmt.Errorf(\"node %q is not allowed to use the dummy peer key\", nodeName)\n\t}\n\n\tif prevNodeName, ok := a.nodeNameByPubKey[pubKey]; ok {\n\t\tif nodeName != prevNodeName {\n\t\t\treturn fmt.Errorf(\"detected duplicate public key. \"+\n\t\t\t\t\"node %q uses same key as existing node %q\", nodeName, prevNodeName)\n\t\t}\n\t}\n\n\tpeer := a.peerByNodeName[nodeName]\n\n\t// Reinitialize peer if its public key changed.\n\tif peer != nil && peer.pubKey != pubKey {\n\t\ta.logger.Debug(\n\t\t\t\"Pubkey has changed\",\n\t\t\tlogfields.NodeName, nodeName,\n\t\t)\n\t\tif err := a.deletePeerByPubKey(peer.pubKey); err != nil {\n\t\t\treturn err\n\t\t}\n\t\tpeer = nil\n\t}\n","sourceCodeStart":519,"sourceCodeEnd":555,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/wireguard/agent/agent.go#L519-L555","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// on the cloned node\n// before\nrm /var/lib/cilium/wg  # (stop cilium-agent first)\n// after\nsystemctl restart cilium-agent  # generates a fresh key pair","handlingStrategy":"validation","validationCode":"func ensureUniqueKey(keyHex, nodeName string, keyToNode map[string]string) error {\n    if owner, ok := keyToNode[keyHex]; ok && owner != nodeName {\n        return fmt.Errorf(\"key already owned by node %q\", owner)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := updatePeer(nodeName, key); err != nil {\n    if strings.Contains(err.Error(), \"duplicate public key\") {\n        // clone detected: force key regeneration on the node\n    }\n}","preventionTips":["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"],"tags":["wireguard","duplicate-key","node-identity","cilium"],"backgroundTag":"duplicate-public-key","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}