{"record":{"id":"7f1a5a6ce5bf1e24","repo":"kubernetes/kops","slug":"error-fingerprinting-ssh-public-key-v","errorCode":null,"errorMessage":"error fingerprinting SSH public key: %v","messagePattern":"error fingerprinting SSH public key: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/sshcredentials/fingerprint.go","lineNumber":37,"sourceCode":"import (\n\t\"bytes\"\n\t\"crypto/md5\"\n\t\"fmt\"\n\n\t\"golang.org/x/crypto/ssh\"\n)\n\nfunc Fingerprint(pubkey string) (string, error) {\n\tsshPublicKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pubkey))\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error parsing SSH public key: %v\", err)\n\t}\n\n\t// compute fingerprint to serve as id\n\th := md5.New()\n\t_, err = h.Write(sshPublicKey.Marshal())\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error fingerprinting SSH public key: %v\", err)\n\t}\n\tid := formatFingerprint(h.Sum(nil))\n\treturn id, nil\n}\n\nfunc formatFingerprint(data []byte) string {\n\tvar buf bytes.Buffer\n\n\tfor i, b := range data {\n\t\ts := fmt.Sprintf(\"%0.2x\", b)\n\t\tif i != 0 {\n\t\t\tbuf.WriteString(\":\")\n\t\t}\n\t\tbuf.WriteString(s)\n\t}\n\treturn buf.String()\n}\n","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/sshcredentials/fingerprint.go#L19-L55","documentation":"FingerprintSSHKey computes an identifier for an SSH public key by marshaling the key and hashing it with MD5; the hex digest becomes the key's id. This error wraps any failure returned by the hash writer itself. In practice hash.Write never fails, so this is effectively an unreachable defensive branch.","triggerScenarios":"Calling FingerprintSSHKey (via kops get sshpublickeys, mirroring SSH credentials, or kops create sshpublickey) when h.Write on the md5 hash of sshPublicKey.Marshal() returns a non-nil error.","commonSituations":"Practically never seen in the field; it can only appear if the crypto/hash writer is somehow broken (memory/hash state corruption). More commonly the surrounding code fails for a bad key file or unparseable key, which produces a different error.","solutions":["Retry the operation; this is a transient/unexpected internal failure","Verify the SSH public key file parses correctly (ssh-keygen -lf <file>) since upstream parse failures are the usual real cause of problems in this path","If reproducible, file a bug with the key format and kOps version"],"exampleFix":"// before\npubkey, err := os.ReadFile(\"id_rsa\") // binary/private key by mistake\nid, err := FingerprintSSHKey(pubkey)\n// after\npubkey, err := os.ReadFile(\"id_rsa.pub\") // use the .pub public key file\nid, err := FingerprintSSHKey(pubkey)","handlingStrategy":"try-catch","validationCode":"// Go: verify the key is a parseable SSH public key before fingerprinting\n_, _, _, _, err := ssh.ParseAuthorizedKey(pubkeyBytes)\nif err != nil {\n\treturn fmt.Errorf(\"not a valid SSH public key: %w\", err)\n}","typeGuard":"func isSSHAuthorizedKey(b []byte) bool {\n\t_, _, _, _, err := ssh.ParseAuthorizedKey(b)\n\treturn err == nil\n}","tryCatchPattern":"id, err := sshcredentials.FingerprintSSHKey(pubkey)\nif err != nil {\n\treturn fmt.Errorf(\"fingerprinting ssh public key: %w\", err) // retry once on transient failure\n}","preventionTips":["Always pass the contents of the .pub file, never the private key","Pre-validate keys with `ssh-keygen -lf` or golang.org/x/crypto/ssh before submitting","Treat this error as unexpected and log full context for a bug report"],"tags":["ssh","fingerprint","md5"],"backgroundTag":"ssh-key-parse-failure","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"}