{"record":{"id":"21edb2c33c7f6c1f","repo":"hashicorp/packer","slug":"marshal-public-key-w","errorCode":null,"errorMessage":"marshal public key: %w","messagePattern":"marshal public key: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/attestation/sign_key.go","lineNumber":229,"sourceCode":"\t}\n\n\tpublicKeyPEM, err := marshalPublicKeyPEM(signer.Public())\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\tpublicKey, _, err := loadPEMPublicKey(publicKeyPEM)\n\tif err != nil {\n\t\treturn nil, nil, err\n\t}\n\n\treturn publicKey, publicKeyPEM, nil\n}\n\nfunc marshalPublicKeyPEM(publicKey crypto.PublicKey) ([]byte, error) {\n\tencoded, err := x509.MarshalPKIXPublicKey(publicKey)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"marshal public key: %w\", err)\n\t}\n\n\treturn pem.EncodeToMemory(&pem.Block{Type: \"PUBLIC KEY\", Bytes: encoded}), nil\n}\n\nfunc sha256Hex(value []byte) string {\n\tdigest := sha256.Sum256(value)\n\treturn hex.EncodeToString(digest[:])\n}\n","sourceCodeStart":211,"sourceCodeEnd":239,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/internal/attestation/sign_key.go#L211-L239","documentation":"marshalPublicKeyPEM wraps a failure from x509.MarshalPKIXPublicKey, the step that converts a parsed key into SubjectPublicKeyInfo DER before PEM-encoding. This function is used to derive the public counterpart of a loaded signer or Fulcio certificate. MarshalPKIXPublicKey fails almost exclusively when the crypto.PublicKey is of a type the standard library cannot serialize into SPKI form (in practice: unsupported key algorithms; RSA, ECDSA and Ed25519 always succeed).","triggerScenarios":"Any caller — loadPEMSigner, loadPEMPrivateKeyAsPublic, or newSigstoreVerifierFromPublicKey — passes a crypto.PublicKey that x509.MarshalPKIXPublicKey cannot marshal, e.g. a DSA public key recovered from a PKCS#8 blob, or a custom/foreign key type implementing crypto.Signer with an exotic PublicKey().","commonSituations":"A DSA private key in PKCS#8 format parses fine via ParsePKCS8PrivateKey (implementing crypto.Signer) but its DSA public key cannot be marshalled to SPKI, producing this error. Also possible when a Fulcio certificate carries an unexpected public-key algorithm, or with exotic smartcard/HSM-backed signer types whose Public() returns a non-standard type.","solutions":["Identify the key algorithm ('openssl pkey -in key.pem -text -noout'); if it is DSA, regenerate the key as RSA, ECDSA (P-256/384/521) or Ed25519.","Convert the key to a supported algorithm: 'openssl genpkey -algorithm RSA ...' or 'openssl genpkey -algorithm ED25519', then update the configured signer.","If the key is fine but the file is not, re-export it in PKCS#8 ('openssl pkcs8 -topk8 -nocrypt') so parsing yields a standard key type.","If this happens with a certificate-derived key, check the certificate's Public Key Algorithm field ('openssl x509 -in cert.pem -noout -text'); use a certificate with an RSA/EC/Ed25519 key.","Inspect the wrapped inner error from MarshalPKIXPublicKey — it names the specific marshal failure."],"exampleFix":"// before: DSA key in PKCS#8 -> parses, but MarshalPKIXPublicKey fails\n// signer.pem: DSA PRIVATE KEY\n// after: generate a supported key and reconfigure\n//   openssl genpkey -algorithm ED25519 -out signer.pem\n// signer ref = signer.pem","handlingStrategy":"validation","validationCode":"// pre-flight: round-trip the key's public part through SPKI marshal\nfunc canMarshalPublicKey(path string) error {\n\tdata, _ := os.ReadFile(path)\n\tblock, _ := pem.Decode(data)\n\tif block == nil {\n\t\treturn fmt.Errorf(\"no PEM block\")\n\t}\n\tkey, err := x509.ParsePKCS8PrivateKey(block.Bytes)\n\tif err != nil {\n\t\treturn err\n\t}\n\tsigner, ok := key.(crypto.Signer)\n\tif !ok {\n\t\treturn fmt.Errorf(\"not a crypto.Signer\")\n\t}\n\tif _, err := x509.MarshalPKIXPublicKey(signer.Public()); err != nil {\n\t\treturn fmt.Errorf(\"algorithm %T not SPKI-marshalable: %w\", signer.Public(), err)\n\t}\n\treturn nil\n}","typeGuard":"func isSPKIMarshalable(pub crypto.PublicKey) bool {\n\tswitch pub.(type) {\n\tcase *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:\n\t\treturn true\n\tdefault:\n\t\treturn false // e.g. *dsa.PublicKey, custom key types\n\t}\n}","tryCatchPattern":"signer, verifier, err := loadPEMSigner(keyPath)\nif err != nil {\n\tif strings.Contains(err.Error(), \"marshal public key\") {\n\t\treturn fmt.Errorf(\"signer %s: public key algorithm not supported by x509.MarshalPKIXPublicKey; regenerate as RSA/ECDSA/Ed25519: %w\", keyPath, err)\n\t}\n\treturn err\n}","preventionTips":["Restrict key generation to RSA, ECDSA (P-256/384/521), or Ed25519; DSA keys are the classic trigger.","Check the algorithm at key-provisioning time with 'openssl pkey -in key.pem -text -noout'.","Keep keys in PKCS#8 PEM so ParsePKCS8PrivateKey yields a standard Go key type.","Test key loading for every key format your pipeline can emit, not just the happy path."],"tags":["go","crypto","x509","key-format"],"backgroundTag":"unsupported-key-format","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}