{"record":{"id":"70cb1705924d934a","repo":"hashicorp/nomad","slug":"private-key-is-not-a-valid-format","errorCode":null,"errorMessage":"private key is not a valid format","messagePattern":"private key is not a valid format","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"helper/tlsutil/generate.go","lineNumber":335,"sourceCode":"\tif block == nil {\n\t\treturn nil, fmt.Errorf(\"no PEM-encoded data found\")\n\t}\n\n\tswitch block.Type {\n\tcase \"EC PRIVATE KEY\":\n\t\treturn x509.ParseECPrivateKey(block.Bytes)\n\n\tcase \"RSA PRIVATE KEY\":\n\t\treturn x509.ParsePKCS1PrivateKey(block.Bytes)\n\n\tcase \"PRIVATE KEY\":\n\t\tsigner, err := x509.ParsePKCS8PrivateKey(block.Bytes)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tpk, ok := signer.(crypto.Signer)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"private key is not a valid format\")\n\t\t}\n\n\t\treturn pk, nil\n\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown PEM block type for signing key: %s\", block.Type)\n\t}\n}\n\nfunc Verify(caString, certString, dns string) error {\n\troots := x509.NewCertPool()\n\tok := roots.AppendCertsFromPEM([]byte(caString))\n\tif !ok {\n\t\treturn fmt.Errorf(\"failed to parse root certificate\")\n\t}\n\n\tcert, err := parseCert(certString)\n\tif err != nil {","sourceCodeStart":317,"sourceCodeEnd":353,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/helper/tlsutil/generate.go#L317-L353","documentation":"ParseSigner decoded a PEM PRIVATE KEY block and x509.ParsePKCS8PrivateKey succeeded, but the resulting key does not implement crypto.Signer (e.g. it parsed to an *encryptedPKCS8Container-like or non-key type such as x509 Certificate data mislabeled, or PKCS8 payload holding an unusable type). The key is syntactically valid PKCS#8 but not a signable private key.","triggerScenarios":"A PKCS#8 PRIVATE KEY block whose DER payload decodes to a type not implementing crypto.Signer — typically because the block actually contains a certificate or public key mislabeled as PRIVATE KEY, or an exotic/unsupported PKCS8 algorithm payload.","commonSituations":"Mislabeled PEM blocks (certificate bytes under a PRIVATE KEY header); keys exported by tooling with unsupported PKCS#8 algorithm identifiers; hand-edited PEM bundles where block contents and types no longer match.","solutions":["Regenerate the private key with a supported algorithm (ECDSA P-256 or RSA) using tlsutil.GeneratePrivateKey or standard tooling.","Verify each PEM block's contents match its declared type; do not relabel blocks.","Convert the key to a supported format: openssl pkcs8 -topk8 -nocrypt with EC/RSA, then retry ParseSigner.","If a public key or cert was pasted by mistake, supply the actual private key."],"exampleFix":"// before\n// certPEM bytes pasted under \"-----BEGIN PRIVATE KEY-----\" header\nsigner, err := tlsutil.ParseSigner(mislabeledPEM)\n// after\nsigner, err := tlsutil.ParseSigner(realKeyPEM) // header matches EC/RSA PRIVATE KEY contents","handlingStrategy":"type-guard","validationCode":"func signerYieldsSigner(s string) error {\n\tblock, _ := pem.Decode([]byte(s))\n\tif block == nil || block.Type != \"PRIVATE KEY\" { return nil }\n\tk, err := x509.ParsePKCS8PrivateKey(block.Bytes)\n\tif err != nil { return err }\n\tif _, ok := k.(crypto.Signer); !ok {\n\t\treturn fmt.Errorf(\"PKCS8 payload %T is not a crypto.Signer\", k)\n\t}\n\treturn nil\n}","typeGuard":"func isUsablePKCS8Signer(block *pem.Block) bool {\n\tif block == nil || block.Type != \"PRIVATE KEY\" { return false }\n\tk, err := x509.ParsePKCS8PrivateKey(block.Bytes)\n\treturn err == nil\n}\n// plus, after parse: _, ok := k.(crypto.Signer)","tryCatchPattern":"signer, err := tlsutil.ParseSigner(keyPEM)\nif err != nil {\n\tif strings.Contains(err.Error(), \"private key is not a valid format\") {\n\t\treturn fmt.Errorf(\"PKCS8 key payload is not signable; regenerate as ECDSA/RSA: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Regenerate keys with standard ECDSA P-256 or RSA; avoid exotic PKCS#8 algorithms.","Never relabel PEM headers; keep block bytes and type declarations consistent.","Round-trip keys through openssl to verify format before storing.","After ParsePKCS8PrivateKey in custom code, always assert crypto.Signer."],"tags":["tls","pkcs8","private-key","key-format"],"backgroundTag":"invalid-private-key-format","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}