{"record":{"id":"2c8bb1c7d9e40f4c","repo":"kubernetes/kops","slug":"failed-to-parse-public-key-w","errorCode":null,"errorMessage":"failed to parse public key: %w","messagePattern":"failed to parse public key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/bootstrap/pkibootstrap/pkiverifier/verifier.go","lineNumber":157,"sourceCode":"\tif err := v.client.Get(ctx, id, &host); err != nil {\n\t\tif apierrors.IsNotFound(err) {\n\t\t\treturn nil, nil, fmt.Errorf(\"host not found for %v\", id)\n\t\t}\n\t\treturn nil, nil, fmt.Errorf(\"error getting host %v: %w\", id, err)\n\t}\n\n\t// TODO: Check instance-group matches request (does it matter?)\n\n\tif host.Spec.PublicKey == \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"host %v did not have public-key\", id)\n\t}\n\tinstanceGroup := host.Spec.InstanceGroup\n\tif instanceGroup == \"\" {\n\t\treturn nil, nil, fmt.Errorf(\"host %v did not have spec.instanceGroup\", id)\n\t}\n\tpubKey, err := pki.ParsePEMPublicKey([]byte(host.Spec.PublicKey))\n\tif err != nil {\n\t\treturn nil, nil, fmt.Errorf(\"failed to parse public key: %w\", err)\n\t}\n\n\tvar sans []string\n\n\tresult := &bootstrap.VerifyResult{\n\t\tNodeName:          nodeName,\n\t\tInstanceGroupName: instanceGroup,\n\t\tCertificateNames:  sans,\n\t}\n\n\treturn result, pubKey.Key, nil\n}\n\nfunc verifySignature(signingKey crypto.PublicKey, payload []byte, signature []byte) bool {\n\tattestHash := sha256.Sum256(payload)\n\tswitch signingKey := signingKey.(type) {\n\tcase *ecdsa.PublicKey:\n\t\tklog.Infof(\"attestHash %x\", attestHash)","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/bootstrap/pkibootstrap/pkiverifier/verifier.go#L139-L175","documentation":"The Host's spec.publicKey is non-empty but could not be parsed as a PEM public key by pki.ParsePEMPublicKey. The wrapped error from the parser indicates the actual problem (bad PEM armor, unsupported key type, truncated data).","triggerScenarios":"VerifyToken -> getSigningKey calls ParsePEMPublicKey on host.Spec.PublicKey and it errors: field holds a private key instead of a public key, wrong PEM block type (CERTIFICATE instead of PUBLIC KEY), SSH-format key instead of PKIX PEM, whitespace/base64 corruption from YAML indentation, or unsupported curve (e.g. secp256k1).","commonSituations":"Pasting an SSH authorized_keys line instead of a PKIX PEM public key; YAML multiline indentation mangling the base64 body; storing the certificate rather than the public key; generating keys with an algorithm Go's crypto/x509 cannot parse.","solutions":["Regenerate with supported tooling: openssl ecparam -name prime256v1 -genkey -noout -out key.pem && openssl ec -in key.pem -pubout, then store the BEGIN PUBLIC KEY block in spec.publicKey","Inspect the stored value (kubectl get host ... -o jsonpath='{.spec.publicKey}') and fix PEM armor/indentation/corruption","Ensure the block is -----BEGIN PUBLIC KEY----- (PKIX), not a certificate or SSH-format key","Use an ECDSA key type supported by Go/verifier (the signature check only supports *ecdsa.PublicKey)"],"exampleFix":"// before (SSH format, unparsable)\n// spec:\n//   publicKey: ssh-rsa AAAAB3Nza...\n\n// after (PKIX ECDSA PEM)\n// spec:\n//   publicKey: |\n//     -----BEGIN PUBLIC KEY-----\n//     MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...\n//     -----END PUBLIC KEY-----","handlingStrategy":"validation","validationCode":"pub, err := pki.ParsePEMPublicKey([]byte(host.Spec.PublicKey))\nif err != nil {\n    return fmt.Errorf(\"spec.publicKey for %s is not a valid PKIX PEM public key: %w\", nodeName, err)\n}\nif _, ok := pub.Key.(*ecdsa.PublicKey); !ok {\n    return fmt.Errorf(\"spec.publicKey for %s must be an ECDSA key\", nodeName)\n}","typeGuard":"func isParseableECDSAPublicKey(pemStr string) bool {\n    k, err := pki.ParsePEMPublicKey([]byte(pemStr))\n    if err != nil {\n        return false\n    }\n    _, ok := k.Key.(*ecdsa.PublicKey)\n    return ok\n}","tryCatchPattern":"result, err := verifier.VerifyToken(ctx, req, token, body)\nif err != nil {\n    var perr *pki.ParseError // or inspect wrapped error\n    if strings.Contains(err.Error(), \"failed to parse public key\") {\n        return fmt.Errorf(\"fix spec.publicKey PEM format on the Host object: %w\", err)\n    }\n    return err\n}","preventionTips":["Store only PKIX 'BEGIN PUBLIC KEY' ECDSA (prime256v1) blocks in spec.publicKey","Use YAML block scalars (|) with correct indentation to avoid base64 corruption","Never store SSH-format keys or certificates in spec.publicKey","Pre-validate the PEM with pki.ParsePEMPublicKey at Host creation time"],"tags":["pki","pem","configuration","key-format"],"backgroundTag":"invalid-public-key-format","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"}