slackhq/nebula · error
ErrInvalidPEMX25519PrivateKeyBanner
ErrInvalidPEMX25519PrivateKeyBanner
Error message
bytes did not contain a proper X25519 private key banner
What it means
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.
Source
Thrown at cert/errors.go:30
ErrNotCA = errors.New("certificate is not a CA")
ErrNotSelfSigned = errors.New("certificate is not self-signed")
ErrBlockListed = errors.New("certificate is in the block list")
ErrFingerprintMismatch = errors.New("certificate fingerprint did not match")
ErrSignatureMismatch = errors.New("certificate signature did not match")
ErrInvalidPublicKey = errors.New("invalid public key")
ErrInvalidPrivateKey = errors.New("invalid private key")
ErrPublicPrivateCurveMismatch = errors.New("public key does not match private key curve")
ErrPublicPrivateKeyMismatch = errors.New("public key and private key are not a pair")
ErrPrivateKeyEncrypted = errors.New("private key must be decrypted")
ErrCaNotFound = errors.New("could not find ca for the certificate")
ErrUnknownVersion = errors.New("certificate version unrecognized")
ErrCertPubkeyPresent = errors.New("certificate has unexpected pubkey present")
ErrCurveMismatch = errors.New("certificate curve does not match CA")
ErrInvalidPEMBlock = errors.New("input did not contain a valid PEM encoded block")
ErrInvalidPEMCertificateBanner = errors.New("bytes did not contain a proper certificate banner")
ErrInvalidPEMX25519PublicKeyBanner = errors.New("bytes did not contain a proper X25519 public key banner")
ErrInvalidPEMX25519PrivateKeyBanner = errors.New("bytes did not contain a proper X25519 private key banner")
ErrInvalidPEMEd25519PublicKeyBanner = errors.New("bytes did not contain a proper Ed25519 public key banner")
ErrInvalidPEMEd25519PrivateKeyBanner = errors.New("bytes did not contain a proper Ed25519 private key banner")
ErrNoPeerStaticKey = errors.New("no peer static key was present")
ErrNoPayload = errors.New("provided payload was empty")
ErrMissingDetails = errors.New("certificate did not contain details")
ErrEmptySignature = errors.New("empty signature")
ErrEmptyRawDetails = errors.New("empty rawDetails not allowed")
)
type ErrInvalidCertificateProperties struct {
str string
}
func NewErrInvalidCertificateProperties(format string, a ...any) error {
return &ErrInvalidCertificateProperties{fmt.Sprintf(format, a...)}
}View on GitHub (pinned to dd8f660c0a)
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
Example fix
// before
keyBytes, _ := os.ReadFile("ed25519.key") // wrong algorithm
// after
keyBytes, _ := os.ReadFile("x25519.key") // file with proper X25519 PRIVATE KEY banner Defensive patterns
Strategy: validation
Validate before calling
block, _ := pem.Decode(keyBytes)
if block == nil || !strings.Contains(block.Type, "X25519 PRIVATE KEY") {
return fmt.Errorf("not an X25519 private key PEM")
} Type guard
func isX25519PrivateKeyPEM(b []byte) bool {
blk, _ := pem.Decode(b)
return blk != nil && strings.Contains(blk.Type, "X25519 PRIVATE KEY")
} Try / catch
cert, err := loadX25519PrivKey(keyBytes)
if errors.Is(err, cert.ErrInvalidPEMX25519PrivateKeyBanner) {
// wrong key file/algorithm: surface config guidance
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ErrInvalidPEMEd25519PublicKeyBanner
- ErrInvalidPEMEd25519PrivateKeyBanner
- ErrTruncatedPEMBlock
- Empty configuration
- group should contain a single value, an array with more than
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/00d760d14d8b3d96.
Report an issue: GitHub.