{"record":{"id":"31a0537b8f517fe3","repo":"kubernetes/kops","slug":"no-keypairid-for-q","errorCode":null,"errorMessage":"no keypairID for %q","messagePattern":"no keypairID for %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"nodeup/pkg/model/context.go","lineNumber":271,"sourceCode":"\treturn kubeConfig.GetConfig()\n}\n\n// GetBootstrapCert requests a certificate keypair from kops-controller.\nfunc (c *NodeupModelContext) GetBootstrapCert(name string, signer string) (cert, key fi.Resource, err error) {\n\tif c.IsMaster {\n\t\tpanic(\"control plane nodes can't get certs from kops-controller\")\n\t}\n\tb, ok := c.bootstrapCerts[name]\n\tif !ok {\n\t\tb = &nodetasks.BootstrapCert{\n\t\t\tCert: &fi.NodeupTaskDependentResource{},\n\t\t\tKey:  &fi.NodeupTaskDependentResource{},\n\t\t}\n\t\tc.bootstrapCerts[name] = b\n\t}\n\tc.bootstrapKeypairIDs[signer] = c.NodeupConfig.KeypairIDs[signer]\n\tif c.bootstrapKeypairIDs[signer] == \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"no keypairID for %q\", signer)\n\t}\n\treturn b.Cert, b.Key, nil\n}\n\n// BuildBootstrapKubeconfig generates a kubeconfig with a client certificate from either kops-controller or the state store.\nfunc (c *NodeupModelContext) BuildBootstrapKubeconfig(name string, ctx *fi.NodeupModelBuilderContext) (fi.Resource, error) {\n\tcert, key, err := c.GetBootstrapCert(name, fi.CertificateIDCA)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tkubeConfig := &nodetasks.KubeConfig{\n\t\tName: name,\n\t\tCert: cert,\n\t\tKey:  key,\n\t\tCA:   fi.NewStringResource(c.NodeupConfig.CAs[fi.CertificateIDCA]),\n\t}\n\tif c.HasAPIServer {","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/nodeup/pkg/model/context.go#L253-L289","documentation":"GetBootstrapCert looks up the keypair ID for the given signer in NodeupConfig.KeypairIDs; nodeup refuses to request bootstrap certificates from kops-controller when the signer has no keypair ID recorded. This means the nodeup config was generated without the keypair mapping the node needs to bootstrap its certificates.","triggerScenarios":"NodeupConfig.KeypairIDs lacks an entry for the signer (typically \"kubernetes-ca\" used via BuildBootstrapKubeconfig, buildKubeletServingCertificate, or buildCiliumEtcdSecrets) on a non-master node, so the map lookup returns \"\" and GetBootstrapCert fails.","commonSituations":"Stale or truncated nodeup.conf from an older kOps version that didn't populate KeypairIDs; cluster upgraded across kOps versions where the bootstrap-protocol config changed; node bootstrapping with a config generated for a different role.","solutions":["Regenerate the nodeup config by re-running `kops update cluster` / `kops replace` so KeypairIDs is populated, then re-run nodeup","Upgrade nodeup and kops-controller to matching cluster kOps versions (e.g. `kops upgrade cluster` then rolling-replace) since older versions omitted KeypairIDs","Verify the keyset (e.g. \"kubernetes-ca\") exists in the state store: `kops get keypairs` and `kops create keypair kubernetes-ca` if missing","Check that the instance group role matches the nodeup config being applied (don't reuse a config from another node role)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before nodeup builds bootstrap certs, check the config map\nif signerID := nodeupConfig.KeypairIDs[signer]; signerID == \"\" {\n    return fmt.Errorf(\"nodeup config missing KeypairIDs entry for %q; regenerate config with kops update cluster\", signer)\n}","typeGuard":null,"tryCatchPattern":"if cert, key, err := ctx.GetBootstrapCert(name, fi.CertificateIDCA); err != nil {\n    if strings.Contains(err.Error(), \"no keypairID\") {\n        klog.Fatalf(\"stale nodeup config (missing KeypairIDs); re-run 'kops update cluster --yes' and restart nodeup: %v\", err)\n    }\n    return err\n}","preventionTips":["Keep nodeup binary and kops-controller on the same version as the cluster","Regenerate nodeup config on every cluster spec change before node bootstrapping","Verify `kops get keypairs` shows the CA keyset before provisioning nodes","Roll nodes via `kops rolling-update cluster` so configs are refreshed"],"tags":["go","nodeup","keypair","bootstrap","tls"],"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-12T12:17:11.808Z"}