{"record":{"id":"3f13940451dbca36","repo":"kubernetes/kops","slug":"error-adding-ssh-public-key-v","errorCode":null,"errorMessage":"error adding SSH public key: %v","messagePattern":"error adding SSH public key: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/kops/create_cluster.go","lineNumber":871,"sourceCode":"\t\t\t\t\tmerr = multierr.Append(merr, err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif merr != nil && len(c.SSHPublicKeys) == 0 {\n\t\t\t\treturn fmt.Errorf(\"error reading SSH public key files %q: %v\", sshPublicKeyPaths, merr)\n\t\t\t}\n\t\t}\n\t}\n\n\tif len(c.SSHPublicKeys) != 0 {\n\t\tsshCredentialStore, err := clientset.SSHCredentialStore(cluster)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\tfor _, data := range c.SSHPublicKeys {\n\t\t\terr = sshCredentialStore.AddSSHPublicKey(ctx, data)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error adding SSH public key: %v\", err)\n\t\t\t}\n\t\t}\n\t}\n\n\t// Can we actually get to this if??\n\tif targetName != \"\" {\n\t\tif isDryrun {\n\t\t\tfmt.Fprintf(out, \"Previewing changes that will be made:\\n\\n\")\n\t\t}\n\n\t\t// TODO: Maybe just embed UpdateClusterOptions in CreateClusterOptions?\n\t\tupdateClusterOptions := &UpdateClusterOptions{}\n\t\tupdateClusterOptions.InitDefaults()\n\n\t\tupdateClusterOptions.Yes = c.Yes\n\t\tupdateClusterOptions.Target = c.Target\n\t\tupdateClusterOptions.OutDir = c.OutDir\n\t\tupdateClusterOptions.ClusterName = cluster.Name","sourceCodeStart":853,"sourceCodeEnd":889,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/cmd/kops/create_cluster.go#L853-L889","documentation":"After the cluster config is persisted, RunCreateCluster adds each provided SSH public key via sshCredentialStore.AddSSHPublicKey. If that call fails, the error is wrapped and returned, leaving the cluster config already written. The cause is usually a state-store write failure for the sshcredentials object.","triggerScenarios":"`kops create cluster --ssh-public-key <file>` where AddSSHPublicKey fails writing to the state store (permissions, connectivity, transient backend error) after the cluster config was created.","commonSituations":"S3/GCS credentials lost between the config write and the key write; transient network drop; state store read-only; malformed key data rejected by the store.","solutions":["Read the wrapped %v for the storage-layer cause.","Retry `kops create sshpublickey <cluster> -i <key>` to add the key to the already-created cluster.","Verify state-store permissions and connectivity.","If the key file is corrupt, regenerate it and re-run."],"exampleFix":"// before\nkops create cluster --ssh-public-key ~/.ssh/broken_key.pub ...\n// after\nssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub\nkops create cluster --ssh-public-key ~/.ssh/id_rsa.pub ...\n# or on the already-created cluster:\nkops create sshpublickey c.k8s.local -i ~/.ssh/id_rsa.pub","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := runCreateCluster(...); err != nil {\n\tif strings.Contains(err.Error(), \"error adding SSH public key\") {\n\t\t// cluster already created; retry just the key upload:\n\t\t// kops create sshpublickey <cluster> -i <keyfile>\n\t}\n\treturn err\n}","preventionTips":["Verify state-store connectivity/permissions before create.","Prefer adding keys post-create with `kops create sshpublickey` for better recovery.","Validate the key file content (starts with ssh-ed25519/ssh-rsa) before upload.","Keep credentials (AWS/GCS) valid for the whole command duration."],"tags":["cli","ssh","state-store"],"backgroundTag":"ssh-public-key-upload-failed","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"}