{"record":{"id":"00d760d14d8b3d96","repo":"slackhq/nebula","slug":"errinvalidpemx25519privatekeybanner","errorCode":"ErrInvalidPEMX25519PrivateKeyBanner","errorMessage":"bytes did not contain a proper X25519 private key banner","messagePattern":"bytes did not contain a proper X25519 private key banner","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cert/errors.go","lineNumber":30,"sourceCode":"\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\n\tErrMissingDetails  = errors.New(\"certificate did not contain details\")\n\tErrEmptySignature  = errors.New(\"empty signature\")\n\tErrEmptyRawDetails = errors.New(\"empty rawDetails not allowed\")\n)\n\ntype ErrInvalidCertificateProperties struct {\n\tstr string\n}\n\nfunc NewErrInvalidCertificateProperties(format string, a ...any) error {\n\treturn &ErrInvalidCertificateProperties{fmt.Sprintf(format, a...)}\n}","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/slackhq/nebula/blob/dd8f660c0ac37903ec4080ca4d3c861ba9342ceb/cert/errors.go#L12-L48","documentation":"ErrInvalidPEMX25519PrivateKeyBanner is thrown when PEM-encoded bytes that should hold an X25519 private key use the wrong '-----BEGIN ...-----' banner type. The library parses PEM blocks and expects the block type to match the key kind it is being asked to decode; a mismatch means the input is either a different key type, a certificate, or corrupt/truncated data.","triggerScenarios":"Passing bytes to an X25519 private key PEM parser whose block type is not the expected X25519 PRIVATE KEY banner — e.g. feeding an Ed25519 key, a public key, or a certificate where an X25519 private key is expected.","commonSituations":"Config files where the private-key and public-key file paths are swapped; keys generated with a different algorithm (Ed25519) pasted into an X25519 field; a certificate file supplied instead of the key file; environment variables pointing at the wrong secret path.","solutions":["Verify the PEM file begins with the correct X25519 private key banner and regenerate/re-export the key with the right algorithm if not","Check that the config path/env var points at the private key file, not the public key or certificate","Regenerate the key with the intended curve (X25519) if it was accidentally created as Ed25519"],"exampleFix":"// before\nkeyBytes, _ := os.ReadFile(\"ed25519.key\") // wrong algorithm\n// after\nkeyBytes, _ := os.ReadFile(\"x25519.key\") // file with proper X25519 PRIVATE KEY banner","handlingStrategy":"validation","validationCode":"block, _ := pem.Decode(keyBytes)\nif block == nil || !strings.Contains(block.Type, \"X25519 PRIVATE KEY\") {\n    return fmt.Errorf(\"not an X25519 private key PEM\")\n}","typeGuard":"func isX25519PrivateKeyPEM(b []byte) bool {\n    blk, _ := pem.Decode(b)\n    return blk != nil && strings.Contains(blk.Type, \"X25519 PRIVATE KEY\")\n}","tryCatchPattern":"cert, err := loadX25519PrivKey(keyBytes)\nif errors.Is(err, cert.ErrInvalidPEMX25519PrivateKeyBanner) {\n    // wrong key file/algorithm: surface config guidance\n}","preventionTips":["Keep private key, public key, and certificate files in distinct, clearly named paths","Validate PEM banners at config load time, before the key is used","Pin key algorithm per environment so curve migrations cannot silently swap files"],"tags":["pem","x25519","key-parsing","config"],"backgroundTag":"invalid-pem-banner","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"}