{"record":{"id":"ca3955f1b413422e","repo":"cilium/cilium","slug":"failed-to-load-or-generate-private-key-w","errorCode":null,"errorMessage":"failed to load or generate private key: %w","messagePattern":"failed to load or generate private key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"pkg/wireguard/agent/agent.go","lineNumber":286,"sourceCode":"\t\t\t\ttypes.NodeEncryptionOptOutLabels+\" label selector\",\n\t\t\tlogfields.Selector, a.config.NodeEncryptionOptOutLabels,\n\t\t)\n\t\tlocalNode.Local.OptOutNodeEncryption = true\n\t\tlocalNode.EncryptionKey = 0\n\t}\n\n\ta.optOut = localNode.Local.OptOutNodeEncryption\n}\n\n// init creates and configures the local WireGuard tunnel device.\nfunc (a *Agent) init() error {\n\ta.Lock()\n\tdefer a.Unlock()\n\n\tvar err error\n\ta.privKey, err = loadOrGeneratePrivKey(a.privKeyPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to load or generate private key: %w\", err)\n\t}\n\n\t// Best-effort MTU computation: account for WireGuard overhead including padding.\n\t// Without this, the kernel defaults to 1500 - 80 = 1420, ignoring alignment padding.\n\t// Worst case we set 1500 - 95 = 1405; the mtuReconciler will adjust once the MTU table is populated.\n\tdeviceMTU := mtu.EthernetMTU\n\tif mtuRoute, _, _, found := a.mtuTable.GetWatch(a.db.ReadTxn(), mtu.MTURouteByPrefix(mtu.DefaultPrefixV4)); found {\n\t\tdeviceMTU = mtuRoute.DeviceMTU\n\t}\n\tlinkMTU := deviceMTU - mtu.WireguardOverhead\n\n\tlink := &netlink.Wireguard{\n\t\tLinkAttrs: netlink.LinkAttrs{\n\t\t\tName: types.IfaceName,\n\t\t\tMTU:  linkMTU,\n\t\t},\n\t}\n","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/pkg/wireguard/agent/agent.go#L268-L304","documentation":"The agent's init step loads the WireGuard private key from privKeyPath or generates a new one; any failure (unreadable file, invalid key data, unwritable directory) is wrapped as \"failed to load or generate private key\". Without a valid private key the node cannot identify itself on the WireGuard mesh.","triggerScenarios":"loadOrGeneratePrivKey fails because the key file exists but is unreadable/corrupt, its parent directory is missing or not writable, or its content is not a valid curve25519 key.","commonSituations":"Container running as non-root without access to the key path; stale/corrupt key from an interrupted write; read-only root filesystem; key truncated after a node crash.","solutions":["Fix permissions on the private key file and its directory so the agent user can read/write.","Delete the corrupt key file to let the agent generate a fresh one (peers will re-learn the public key).","Ensure the volume backing privKeyPath is writable and persistent.","Inspect the wrapped error to distinguish read vs. generate failure."],"exampleFix":"// before\nchown -R kube-apiserver: /var/lib/cilium/wg  # wrong user\n// after\nchown -R root:root /var/lib/cilium/wg && chmod 700 /var/lib/cilium/wg","handlingStrategy":"validation","validationCode":"// pre-flight: key path must be readable, dir writable\nif info, err := os.Stat(privKeyPath); err == nil && info.Mode().Perm()&0400 == 0 {\n    return errors.New(\"private key file not readable\")\n}\nif err := os.WriteFile(filepath.Join(filepath.Dir(privKeyPath), \".probe\"), nil, 0600); err != nil {\n    return fmt.Errorf(\"key dir not writable: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"if err := agent.Start(ctx); err != nil {\n    if strings.Contains(err.Error(), \"failed to load or generate private key\") {\n        return fmt.Errorf(\"fix permissions or delete corrupt key file: %w\", err)\n    }\n    return err\n}","preventionTips":["Mount the key directory as a writable persistent volume.","Run the agent as the user owning the key path.","Probe writability at container startup."],"tags":["wireguard","private-key","filesystem"],"backgroundTag":"private-key-load-failed","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}