{"record":{"id":"b2d4f531392f63c2","repo":"kubernetes/kops","slug":"the-first-keypair-added-to-a-keyset-must-be-primar","errorCode":null,"errorMessage":"the first keypair added to a keyset must be primary","messagePattern":"the first keypair added to a keyset must be primary","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/kops/create_keypair.go","lineNumber":243,"sourceCode":"\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error reading user provided cert %q: %v\", options.CertPath, err)\n\t\t}\n\n\t\tcert, err = pki.ParsePEMCertificate(certBytes)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error loading certificate %q: %v\", options.CertPath, err)\n\t\t}\n\t}\n\n\tkeyset, err := keyStore.FindKeyset(ctx, name)\n\tvar item *fi.KeysetItem\n\tif os.IsNotExist(err) || (err == nil && keyset == nil) {\n\t\tif options.Primary {\n\t\t\tif keyset, err = fi.NewKeyset(cert, privateKey); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\treturn fmt.Errorf(\"the first keypair added to a keyset must be primary\")\n\t\t}\n\t\titem = keyset.Primary\n\t} else if err != nil {\n\t\treturn fmt.Errorf(\"reading existing keyset: %v\", err)\n\t} else {\n\t\titem, err = keyset.AddItem(cert, privateKey, options.Primary)\n\t}\n\tif err != nil {\n\t\treturn err\n\t}\n\n\terr = keyStore.StoreKeyset(ctx, name, keyset)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error storing user provided keys %q %q: %v\", options.CertPath, options.PrivateKeyPath, err)\n\t}\n\n\tif options.CertPath != \"\" {\n\t\tfmt.Fprintf(out, \"using user provided cert: %v\\n\", options.CertPath)","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/cmd/kops/create_keypair.go#L225-L261","documentation":"kOps requires that the first keypair in a keyset be added as primary. This error is returned when `kops create keypair` finds no existing keyset for the given name but the command was invoked without --primary (options.Primary false), so a non-primary keypair cannot seed a brand-new keyset.","triggerScenarios":"Running `kops create keypair <cluster> <keyset>` where FindKeyset returns not-exist/nil and options.Primary is false — i.e. targeting a keyset that doesn't exist yet without the primary flag.","commonSituations":"Typo in the keyset name so it looks brand-new; intending to add a secondary keypair but the keyset was never created or lives in a different state store/cluster; forgetting --primary on first bootstrap.","solutions":["Add the --primary flag: `kops create keypair <cluster> <keyset> --primary`.","Check the keyset name for typos (an existing keyset accepts a non-primary add).","Confirm you are pointed at the right cluster/state store where the keyset exists.","Create the keyset with a primary keypair before adding secondary ones."],"exampleFix":"// before\nkops create keypair cluster.example.com kubernetes-ca\n// error: the first keypair added to a keyset must be primary\n// after\nkops create keypair cluster.example.com kubernetes-ca --primary","handlingStrategy":"validation","validationCode":"// Pre-check whether the keyset exists before invoking with a non-primary add\nkeyset, err := keyStore.FindKeyset(ctx, name)\nexists := err == nil && keyset != nil\nif !exists && !primaryFlag {\n    return errors.New(\"keyset does not exist: must pass --primary\")\n}","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"first keypair added to a keyset must be primary\") {\n    // re-run the command with --primary\n}","preventionTips":["Always use --primary when bootstrapping a new keyset.","Double-check the keyset name before adding non-primary keypairs.","Confirm you are connected to the state store/cluster where the keyset lives."],"tags":["keypair","keystore","cli-flag"],"backgroundTag":"missing-primary-keypair","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"}