{"record":{"id":"72556346a72f96b8","repo":"kubernetes/kops","slug":"error-reading-ssh-key-file-q-v-725563","errorCode":null,"errorMessage":"error reading SSH key file %q: %v","messagePattern":"error reading SSH key file %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/kops/update_cluster.go","lineNumber":298,"sourceCode":"\t}\n\n\tsshCredentialStore, err := clientset.SSHCredentialStore(cluster)\n\tif err != nil {\n\t\treturn results, err\n\t}\n\n\tsecretStore, err := clientset.SecretStore(cluster)\n\tif err != nil {\n\t\treturn results, err\n\t}\n\n\tif c.SSHPublicKey != \"\" {\n\t\tfmt.Fprintf(out, \"--ssh-public-key on update is deprecated - please use `kops create secret --name %s sshpublickey admin -i ~/.ssh/id_rsa.pub` instead\\n\", cluster.ObjectMeta.Name)\n\n\t\tc.SSHPublicKey = utils.ExpandPath(c.SSHPublicKey)\n\t\tauthorized, err := os.ReadFile(c.SSHPublicKey)\n\t\tif err != nil {\n\t\t\treturn results, fmt.Errorf(\"error reading SSH key file %q: %v\", c.SSHPublicKey, err)\n\t\t}\n\t\terr = sshCredentialStore.AddSSHPublicKey(ctx, authorized)\n\t\tif err != nil {\n\t\t\treturn results, fmt.Errorf(\"error adding SSH public key: %v\", err)\n\t\t}\n\n\t\tklog.Infof(\"Using SSH public key: %v\\n\", c.SSHPublicKey)\n\t}\n\n\tvar phase cloudup.Phase\n\tif c.Phase != \"\" {\n\t\tswitch strings.ToLower(c.Phase) {\n\t\tcase string(cloudup.PhaseNetwork):\n\t\t\tphase = cloudup.PhaseNetwork\n\t\tcase string(cloudup.PhaseSecurity), \"iam\": // keeping IAM for backwards compatibility\n\t\t\tphase = cloudup.PhaseSecurity\n\t\tcase string(cloudup.PhaseCluster):\n\t\t\tphase = cloudup.PhaseCluster","sourceCodeStart":280,"sourceCodeEnd":316,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/cmd/kops/update_cluster.go#L280-L316","documentation":"When --ssh-public-key is passed to `kops update cluster` (deprecated), the command reads the referenced file to install it into the cluster's SSH credential store. If os.ReadFile fails — missing file, bad path, permission denied — the error is wrapped as `error reading SSH key file %q: %v`. The path is first expanded via utils.ExpandPath, so ~ resolves to the home directory.","triggerScenarios":"`kops update cluster --ssh-public-key <path>` where <path> does not exist, is a directory, or is unreadable by the current user (after ~ expansion).","commonSituations":"Deprecated flag usage in old scripts; file moved/renamed (id_rsa.pub regenerated); running in CI container where the key was never mounted; wrong relative path after changing working directory; permissions tightened by ssh-keygen.","solutions":["Check the file exists and is readable: `ls -l <path>` (after ~ expansion)","Prefer the supported command: `kops create secret --name <cluster> sshpublickey admin -i <path>`","Remove --ssh-public-key from the update invocation once the key is stored"],"exampleFix":"// before\nkops update cluster c.k8s.local --ssh-public-key ~/.ssh/id_ed25519.pub --yes\n// after (file exists, or better:)\nkops create secret --name c.k8s.local sshpublickey admin -i ~/.ssh/id_ed25519.pub\nkops update cluster c.k8s.local --yes","handlingStrategy":"validation","validationCode":"path := utils.ExpandPath(c.SSHPublicKey)\ninfo, err := os.Stat(path)\nif err != nil || info.IsDir() {\n\treturn fmt.Errorf(\"--ssh-public-key %q is not a readable file\", path)\n}\n// then run kops update cluster --ssh-public-key <path>","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Stat the key file before invoking update","Migrate to `kops create secret sshpublickey admin -i <file>` — the update flag is deprecated","Mount the key explicitly in CI containers and use absolute paths","Note that ~ is expanded by kOps, not the shell, when the flag is quoted"],"tags":["cli","ssh","file-io","deprecated"],"backgroundTag":"file-not-found","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"}