{"record":{"id":"8126f9efe7a89cdb","repo":"kubernetes/kops","slug":"no-keypair-id-for-q","errorCode":null,"errorMessage":"no keypair ID for %q","messagePattern":"no keypair ID for %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nodeup/pkg/model/context.go","lineNumber":389,"sourceCode":"\n// BuildPrivateKeyTask builds a task to create the private key file.\nfunc (c *NodeupModelContext) BuildPrivateKeyTask(ctx *fi.NodeupModelBuilderContext, name, path, filename string, owner *string, beforeServices []string) error {\n\treturn c.buildCertificatePairTask(ctx, name, path, filename, owner, beforeServices, false)\n}\n\nfunc (c *NodeupModelContext) buildCertificatePairTask(ctx *fi.NodeupModelBuilderContext, name, path, filename string, owner *string, beforeServices []string, includeCert bool) error {\n\tp := filepath.Join(path, filename)\n\tif !filepath.IsAbs(p) {\n\t\tp = filepath.Join(c.PathSrvKubernetes(), p)\n\t}\n\n\t// We use the keypair ID passed in nodeup.Config instead of the primary\n\t// keypair so that the node will be updated when the primary keypair does\n\t// not match the one that we are using.\n\tkeypairID := c.NodeupConfig.KeypairIDs[name]\n\tif keypairID == \"\" {\n\t\t// kOps bug where KeypairID was not populated for the node role.\n\t\treturn fmt.Errorf(\"no keypair ID for %q\", name)\n\t}\n\n\tkeyset, err := c.KeyStore.FindKeyset(ctx.Context(), name)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif keyset == nil {\n\t\treturn fmt.Errorf(\"keyset %q not found\", name)\n\t}\n\n\titem := keyset.Items[keypairID]\n\tif item == nil {\n\t\treturn fmt.Errorf(\"did not find keypair %s for %s\", keypairID, name)\n\t}\n\n\tif includeCert {\n\t\tcertificate := item.Certificate\n\t\tif certificate == nil {","sourceCodeStart":371,"sourceCodeEnd":407,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/nodeup/pkg/model/context.go#L371-L407","documentation":"buildCertificatePairTask reads the keypair ID for the named keyset from NodeupConfig.KeypairIDs before writing cert/key files. If the ID is empty the nodeup config was not populated for this node role — the code comments call it a kOps bug where KeypairID was not populated for the node role — so it refuses to materialize files from the wrong (primary) keypair.","triggerScenarios":"Calling BuildCertificatePairTask, BuildPrivateKeyTask, or Build for a keyset name (e.g. \"kubelet\", \"apiserver-proxy\") that has no entry in NodeupConfig.KeypairIDs because the serialized nodeup config predates KeypairIDs or was generated without that keypair.","commonSituations":"Rolling nodes after a kOps upgrade where nodeup.conf on the instance still has the old schema; mixed-version clusters where an old nodeup binary pairs with a new config or vice versa.","solutions":["Re-run `kops update cluster --yes` to regenerate nodeup config with KeypairIDs populated, then restart nodeup / replace the instance","Ensure nodeup binary and cluster kOps version match (`kops rolling-update cluster` refreshes assets)","Verify `kops get keypairs` shows the keyset and note its primary ID; confirm it appears in the node's nodeup.conf","If it persists, file/check kOps issues — the code itself marks this as a known kOps bug class"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if kpID := nodeupConfig.KeypairIDs[name]; kpID == \"\" {\n    return fmt.Errorf(\"KeypairIDs[%q] empty in nodeup config; regenerate nodeup config\", name)\n}","typeGuard":null,"tryCatchPattern":"err := c.BuildCertificatePairTask(ctx, \"kubelet\", \"/srv/kubernetes\", \"kubelet\", owner, nil)\nif err != nil && strings.Contains(err.Error(), \"no keypair ID\") {\n    return fmt.Errorf(\"stale nodeup config for role; re-run kops update cluster: %w\", err)\n}","preventionTips":["Never hand-edit nodeup.conf; always generate via kops","Match nodeup binary version to cluster version","After kOps upgrades, rolling-update nodes to refresh configs","Alert on nodeup errors mentioning KeypairID"],"tags":["go","nodeup","keypair","config"],"backgroundTag":"missing-keypair-id","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}