{"record":{"id":"2d5409ea1dc15b08","repo":"kubernetes/kops","slug":"error-reading-ssh-public-key-v","errorCode":null,"errorMessage":"error reading SSH public key: %v","messagePattern":"error reading SSH public key: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/sshkey.go","lineNumber":123,"sourceCode":"\t}\n\tactual.Lifecycle = e.Lifecycle\n\tif actual.Shared {\n\t\t// Don't report tag changes on shared keys\n\t\tactual.Tags = e.Tags\n\t}\n\n\te.ID = actual.ID\n\tif e.IsExistingKey() && *e.Name != \"\" {\n\t\te.KeyFingerprint = actual.KeyFingerprint\n\t}\n\treturn actual, nil\n}\n\nfunc (e *SSHKey) Normalize(c *fi.CloudupContext) error {\n\tif e.KeyFingerprint == nil && e.PublicKey != nil {\n\t\tpublicKey, err := fi.ResourceAsString(e.PublicKey)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error reading SSH public key: %v\", err)\n\t\t}\n\n\t\tkeyFingerprint, err := pki.ComputeAWSKeyFingerprint(publicKey)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error computing key fingerprint for SSH key: %v\", err)\n\t\t}\n\t\tklog.V(2).Infof(\"Computed SSH key fingerprint as %q\", keyFingerprint)\n\t\te.KeyFingerprint = &keyFingerprint\n\t}\n\n\treturn nil\n}\n\nfunc (e *SSHKey) Run(c *fi.CloudupContext) error {\n\treturn fi.CloudupDefaultDeltaRunMethod(e, c)\n}\n\nfunc (s *SSHKey) CheckChanges(a, e, changes *SSHKey) error {","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/sshkey.go#L105-L141","documentation":"SSHKey.Normalize runs before apply to compute the AWS key fingerprint from the user-supplied public key when KeyFingerprint isn't set. If reading the PublicKey resource fails, it errors with \"error reading SSH public key\". This happens on the client side, before any AWS call.","triggerScenarios":"fi.ResourceAsString(e.PublicKey) fails: the --ssh-public-key path doesn't exist, isn't readable, or a resource holder was populated with nil/unresolvable data.","commonSituations":"kops create cluster --ssh-public-key pointing at a missing file; wrong relative path after changing working directory; permission denied on the key file; editing specs by hand with a placeholder path.","solutions":["Check the wrapped error: fix the file path or permissions it reports.","Pass an existing file: kops create cluster --ssh-public-key ~/.ssh/id_rsa.pub.","Verify the file is a readable OpenSSH public key.","Ensure spec files reference absolute or workspace-relative correct paths."],"exampleFix":"// before\nkops create cluster --ssh-public-key=./keys/missing.pub\n// after\nkops create cluster --ssh-public-key=$HOME/.ssh/id_rsa.pub","handlingStrategy":"validation","validationCode":"func validatePubKey(path string) error {\n    fi, err := os.Stat(path)\n    if err != nil { return fmt.Errorf(\"public key not readable: %w\", err) }\n    if fi.IsDir() { return fmt.Errorf(\"%s is a directory\", path) }\n    data, err := os.ReadFile(path)\n    if err != nil { return err }\n    if !bytes.HasPrefix(data, []byte(\"ssh-\")) && !bytes.HasPrefix(data, []byte(\"ecdsa-\")) {\n        return fmt.Errorf(\"%s does not look like an OpenSSH public key\", path)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use absolute paths for --ssh-public-key.","Verify with ssh-keygen -l -f <file> before applying.","Never point at private key files."],"tags":["ssh","public-key","file-read","validation"],"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"}