{"record":{"id":"fab704c15176c325","repo":"slackhq/nebula","slug":"errinvalidprivatekey","errorCode":"ErrInvalidPrivateKey","errorMessage":"invalid private key","messagePattern":"invalid private key","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cert/errors.go","lineNumber":18,"sourceCode":"package cert\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n)\n\nvar (\n\tErrBadFormat                  = errors.New(\"bad wire format\")\n\tErrRootExpired                = errors.New(\"root certificate is expired\")\n\tErrExpired                    = errors.New(\"certificate is expired\")\n\tErrNotCA                      = errors.New(\"certificate is not a CA\")\n\tErrNotSelfSigned              = errors.New(\"certificate is not self-signed\")\n\tErrBlockListed                = errors.New(\"certificate is in the block list\")\n\tErrFingerprintMismatch        = errors.New(\"certificate fingerprint did not match\")\n\tErrSignatureMismatch          = errors.New(\"certificate signature did not match\")\n\tErrInvalidPublicKey           = errors.New(\"invalid public key\")\n\tErrInvalidPrivateKey          = errors.New(\"invalid private key\")\n\tErrPublicPrivateCurveMismatch = errors.New(\"public key does not match private key curve\")\n\tErrPublicPrivateKeyMismatch   = errors.New(\"public key and private key are not a pair\")\n\tErrPrivateKeyEncrypted        = errors.New(\"private key must be decrypted\")\n\tErrCaNotFound                 = errors.New(\"could not find ca for the certificate\")\n\tErrUnknownVersion             = errors.New(\"certificate version unrecognized\")\n\tErrCertPubkeyPresent          = errors.New(\"certificate has unexpected pubkey present\")\n\tErrCurveMismatch              = errors.New(\"certificate curve does not match CA\")\n\n\tErrInvalidPEMBlock                   = errors.New(\"input did not contain a valid PEM encoded block\")\n\tErrInvalidPEMCertificateBanner       = errors.New(\"bytes did not contain a proper certificate banner\")\n\tErrInvalidPEMX25519PublicKeyBanner   = errors.New(\"bytes did not contain a proper X25519 public key banner\")\n\tErrInvalidPEMX25519PrivateKeyBanner  = errors.New(\"bytes did not contain a proper X25519 private key banner\")\n\tErrInvalidPEMEd25519PublicKeyBanner  = errors.New(\"bytes did not contain a proper Ed25519 public key banner\")\n\tErrInvalidPEMEd25519PrivateKeyBanner = errors.New(\"bytes did not contain a proper Ed25519 private key banner\")\n\n\tErrNoPeerStaticKey = errors.New(\"no peer static key was present\")\n\tErrNoPayload       = errors.New(\"provided payload was empty\")\n","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/cert/errors.go#L1-L36","documentation":"ErrInvalidPrivateKey is returned by VerifyPrivateKey when the supplied private key cannot correspond to the certificate's public key: for ed25519 the key length must equal ed25519.PrivateKeySize (checked explicitly to avoid a slice-bounds panic), and for P256/ECDH ecdh.P256().NewPrivateKey(key) fails to parse it.","triggerScenarios":"cert.VerifyPrivateKey on a v2 cert (cert/cert_v2.go:183,192) when the ed25519 key bytes are the wrong length, or the NIST-Curve key bytes are not a valid P256 scalar — wrong-size PEM, hex/base64 decoding issues, or a key from a different curve.","commonSituations":"Passing a public key file where a private key is expected; truncated or armored private key files (PEM header not stripped); key generated on a different curve than the certificate's curve; ed25519 vs P256 mismatch after regeneration.","solutions":["Ensure the key file is the full private key in the expected format and decode armor (pem.Decode) before passing the raw bytes.","Check the key type matches the certificate's curve (ed25519 vs P256) — regenerate the key pair with nebula-cert keygen if mismatched.","Verify key length: 64 bytes for ed25519 private keys; fix cut/paste truncation.","Pair the certificate with the key generated together with it rather than a random existing key."],"exampleFix":"// before\nkey, _ := os.ReadFile(\"host.pub\") // wrong file\ncert.VerifyPrivateKey(hostName, key) // ErrInvalidPrivateKey\n\n// after\nblock, _ := pem.Decode(hostKeyPEM)\ncert.VerifyPrivateKey(hostName, block.Bytes) // matching .key file","handlingStrategy":"validation","validationCode":"const ed25519PrivateKeySize = 64\nif len(key) != ed25519PrivateKeySize {\n    return fmt.Errorf(\"private key must be %d bytes, got %d\", ed25519PrivateKeySize, len(key))\n}","typeGuard":"func isEd25519PrivateKey(key []byte) bool {\n    return len(key) == ed25519.PrivateKeySize\n}","tryCatchPattern":"if err := c.VerifyPrivateKey(hostName, key); errors.Is(err, cert.ErrInvalidPrivateKey) {\n    return fmt.Errorf(\"key file wrong size/curve for cert; regenerate keypair with nebula-cert keygen\")\n}","preventionTips":["Pass the private key file, never the .pub file.","pem.Decode key files before passing raw bytes.","Match key curve to certificate curve (ed25519 vs P256); generate pairs together."],"tags":["private-key","keypair","validation"],"backgroundTag":"invalid-private-key","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"}