{"record":{"id":"1cac0b44e0e40980","repo":"cilium/cilium","slug":"failed-to-generate-wg-private-key-w","errorCode":null,"errorMessage":"failed to generate wg private key: %w","messagePattern":"failed to generate wg private key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/wireguard/agent/agent.go","lineNumber":797,"sourceCode":"\t\t)\n\n\t\tif err := a.deletePeerByPubKey(wgDummyPeerKey); err != nil {\n\t\t\treturn fmt.Errorf(\"while deleting dummy peer: %w\", err)\n\t\t}\n\t}\n\n\tp.finishAllowedIPSync(addedIPs)\n\tp.finishAllowedIPSync(removedIPs)\n\n\treturn nil\n}\n\nfunc loadOrGeneratePrivKey(filePath string) (key wgtypes.Key, err error) {\n\tbytes, err := os.ReadFile(filePath)\n\tif os.IsNotExist(err) {\n\t\tkey, err = wgtypes.GeneratePrivateKey()\n\t\tif err != nil {\n\t\t\treturn wgtypes.Key{}, fmt.Errorf(\"failed to generate wg private key: %w\", err)\n\t\t}\n\n\t\terr = os.WriteFile(filePath, key[:], 0600)\n\t\tif err != nil {\n\t\t\treturn wgtypes.Key{}, fmt.Errorf(\"failed to save wg private key: %w\", err)\n\t\t}\n\n\t\treturn key, nil\n\t} else if err != nil {\n\t\treturn wgtypes.Key{}, fmt.Errorf(\"failed to load wg private key: %w\", err)\n\t}\n\n\treturn wgtypes.NewKey(bytes)\n}\n\n// OnIPIdentityCacheChange implements ipcache.IPIdentityMappingListener\nfunc (a *Agent) OnIPIdentityCacheChange(modType ipcache.CacheModification, cidrCluster cmtypes.PrefixCluster, oldHostIP, newHostIP net.IP,\n\t_ *ipcache.Identity, _ ipcache.Identity, _ uint8, _ *ipcache.K8sMetadata, _ uint8) {","sourceCodeStart":779,"sourceCodeEnd":815,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/wireguard/agent/agent.go#L779-L815","documentation":"loadOrGeneratePrivKey reads the agent's WireGuard private key from disk; if the file does not exist, it generates a new private key with wgtypes.GeneratePrivateKey. Failure of curve25519 key generation (cryptographically near-impossible; indicates RNG/environmental failure) is wrapped here. Called during agent init, so it aborts WireGuard setup.","triggerScenarios":"First-time agent start (no key file) where wgtypes.GeneratePrivateKey returns an error from the underlying randomness source (crypto/rand failure).","commonSituations":"Degraded /dev/urandom or entropy issues in minimal containers/seccomp profiles blocking getrandom, running on unusual sandboxed environments.","solutions":["Verify /dev/urandom is accessible and getrandom(2) is not blocked by the seccomp/apparmor profile","Fix the container runtime security profile to allow crypto/rand syscalls","Ensure the key file directory is writable (also avoids the sibling 'failed to save wg private key')","Restart the node/agent and retry — this failure is almost always transient/environmental"],"exampleFix":"// before (docker run blocking getrandom)\ndocker run --security-opt seccomp:custom.json ...\n// after\n// allow getrandom in the profile, or:\ndocker run --cap-add NET_ADMIN --security-opt seccomp:default ...","handlingStrategy":"try-catch","validationCode":"f, err := os.OpenFile(\"/dev/urandom\", os.O_RDONLY, 0)\nif err != nil {\n    return fmt.Errorf(\"entropy source unavailable: %w\", err)\n}\nf.Close()","typeGuard":null,"tryCatchPattern":"key, err := loadOrGeneratePrivKey(path)\nif err != nil {\n    return fmt.Errorf(\"cannot bootstrap wireguard identity: %w\", err)\n    // abort init; alert operator — do not run without a node key\n}","preventionTips":["Verify /dev/urandom access and getrandom in container seccomp profiles","Pre-provision the key file directory with correct perms (0600 key)","Smoke-test crypto/rand availability in node init scripts","Mount the key path on persistent storage so keys survive restarts"],"tags":["wireguard","key-generation","crypto","init","cilium"],"backgroundTag":"private-key-generation-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}