{"record":{"id":"c519a751cea5ab0e","repo":"slackhq/nebula","slug":"unknown-public-key-type-t","errorCode":null,"errorMessage":"unknown public key type: %T","messagePattern":"unknown public key type: %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkclient/pkclient.go","lineNumber":70,"sourceCode":"\nfunc ecKeyToArray(key *ecdsa.PublicKey) []byte {\n\tx := make([]byte, 32)\n\ty := make([]byte, 32)\n\tkey.X.FillBytes(x)\n\tkey.Y.FillBytes(y)\n\treturn append([]byte{0x04}, append(x, y...)...)\n}\n\nfunc formatPubkeyFromPublicKeyInfoAttr(d []byte) ([]byte, error) {\n\te, err := x509.ParsePKIXPublicKey(d)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tswitch t := e.(type) {\n\tcase *ecdsa.PublicKey:\n\t\treturn ecKeyToArray(e.(*ecdsa.PublicKey)), nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown public key type: %T\", t)\n\t}\n}\n\nfunc (c *PKClient) Test() error {\n\tpub, err := c.GetPubKey()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get public key: %w\", err)\n\t}\n\tout, err := c.DeriveNoise(pub) //do an ECDH with ourselves as a quick test\n\tif err != nil {\n\t\treturn err\n\t}\n\tif len(out) != NoiseKeySize {\n\t\treturn fmt.Errorf(\"got a key of %d bytes, expected %d\", len(out), NoiseKeySize)\n\t}\n\treturn nil\n}\n","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/pkclient/pkclient.go#L52-L88","documentation":"formatPubkeyFromPublicKeyInfoAttr only supports ECDSA public keys from the HSM's certificate/key object; any other key type (RSA, Ed25519, etc.) hits the default branch and fails with this error naming the Go type via %T. The library throws it because it derives the Noise pubkey via ECDH, which requires an EC key.","triggerScenarios":"GetPubKey() calls formatPubkeyFromPublicKeyInfoAttr with a pkcs11 key attribute whose decoded Go type is not *ecdsa.PublicKey — e.g. the HSM slot holds an RSA key with the configured id/label.","commonSituations":"HSM provisioned with an RSA certificate/key instead of EC P-256; multiple objects sharing the same id/label with the wrong one selected first; older HSM provisioning scripts using RSA.","solutions":["Provision the HSM key as an EC P-256 (prime256v1) key instead of RSA","Verify the object id/label in config points at the EC key, not another object","Check the object's attributes (CKA_KEY_TYPE should be CKK_EC)","List slot objects with pkcs11-tool or similar to confirm key type","Re-issue the certificate for the existing EC key if the cert is RSA-signed"],"exampleFix":"// before (HSM provisioning)\npkcs11-tool --keypairgen --key-type rsa:2048\n// after\npkcs11-tool --keypairgen --key-type EC:prime256v1 --usage-derive","handlingStrategy":"validation","validationCode":"// verify key type before New()/Test()\ninfo, _ := session.GetAttributeValue(privKeyObj, []*pkcs11.Attribute{\n    pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, false),\n})\nif binary.BigEndian.Uint16(info[0].Value) != 0x0017 { // CKK_EC\n    return errors.New(\"HSM key must be EC (CKK_EC) for noise derivation\")\n}","typeGuard":"func isECKey(pub interface{}) (*ecdsa.PublicKey, bool) {\n    k, ok := pub.(*ecdsa.PublicKey)\n    return k, ok\n}","tryCatchPattern":"_, err := client.GetPubKey()\nif err != nil {\n    if strings.Contains(err.Error(), \"unknown public key type\") {\n        return fmt.Errorf(\"re-provision HSM key as EC P-256: %w\", err)\n    }\n    return err\n}","preventionTips":["Provision HSM keys as EC P-256 with CKA_DERIVE=true","Keep id/label unique per key object","Audit slot objects with pkcs11-tool --list-objects","Reject RSA keys at provisioning time"],"tags":["pkcs11","hsm","ecdsa","key-type"],"backgroundTag":"unsupported-key-type","analyzedSha":"dd8f660c0ac37903ec4080ca4d3c861ba9342ceb","analyzedAt":"2026-09-03T11:13:55.444Z","contentChangedAt":"2026-09-03T11:13:55.444Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}