slackhq/nebula · error
bytes did not contain a proper nebula encrypted Ed25519/ECDS
Error message
bytes did not contain a proper nebula encrypted Ed25519/ECDSA private key banner
What it means
After a PEM block is successfully decoded, DecryptAndUnmarshalSigningPrivateKey checks the PEM block Type against the known encrypted Nebula private key banners (EncryptedEd25519PrivateKeyBanner, EncryptedECDSAP256PrivateKeyBanner). This error means the PEM parsed fine but its type banner is not one of those, so the library refuses to treat it as an encrypted Nebula signing key.
Source
Thrown at cert/crypto.go:269
}
// DecryptAndUnmarshalSigningPrivateKey will try to pem decode and decrypt an Ed25519/ECDSA private key with
// the given passphrase, returning any other bytes b or an error on failure
func DecryptAndUnmarshalSigningPrivateKey(passphrase, b []byte) (Curve, []byte, []byte, error) {
var curve Curve
k, r := pem.Decode(b)
if k == nil {
return curve, nil, r, fmt.Errorf("input did not contain a valid PEM encoded block")
}
switch k.Type {
case EncryptedEd25519PrivateKeyBanner:
curve = Curve_CURVE25519
case EncryptedECDSAP256PrivateKeyBanner:
curve = Curve_P256
default:
return curve, nil, r, fmt.Errorf("bytes did not contain a proper nebula encrypted Ed25519/ECDSA private key banner")
}
ned, err := UnmarshalNebulaEncryptedData(k.Bytes)
if err != nil {
return curve, nil, r, err
}
var bytes []byte
switch ned.EncryptionMetadata.EncryptionAlgorithm {
case "AES-256-GCM":
bytes, err = aes256Decrypt(passphrase, &ned.EncryptionMetadata.Argon2Parameters, ned.Ciphertext)
if err != nil {
return curve, nil, r, err
}
default:
return curve, nil, r, fmt.Errorf("unsupported encryption algorithm: %s", ned.EncryptionMetadata.EncryptionAlgorithm)
}
View on GitHub (pinned to dd8f660c0a)
Solutions
- Confirm the PEM header is '-----BEGIN NEBULA ED25519 ENCRYPTED PRIVATE KEY-----' or '-----BEGIN NEBULA ECDSA P256 ENCRYPTED PRIVATE KEY-----'
- Pass the correct file: an encrypted Nebula signing private key, not a cert or public key
- Regenerate or re-encrypt the key with EncryptAndMarshalSigningPrivateKey / nebula-cert if it has a foreign banner
Example fix
// before
b, _ := os.ReadFile("host.crt") // PEM type CERTIFICATE
k, _, _, err := cert.DecryptAndUnmarshalSigningPrivateKey(pass, b)
// after
b, _ := os.ReadFile("host.key") // PEM type NEBULA ED25519 ENCRYPTED PRIVATE KEY
k, _, _, err := cert.DecryptAndUnmarshalSigningPrivateKey(pass, b) Defensive patterns
Strategy: validation
Validate before calling
func isEncryptedSigningKey(b []byte) bool {
blk, _ := pem.Decode(b)
if blk == nil {
return false
}
switch blk.Type {
case cert.EncryptedEd25519PrivateKeyBanner, cert.EncryptedECDSAP256PrivateKeyBanner:
return true
}
return false
} Try / catch
curve, key, rest, err := cert.DecryptAndUnmarshalSigningPrivateKey(pass, b)
if err != nil {
if strings.Contains(err.Error(), "proper nebula encrypted") {
return fmt.Errorf("wrong PEM type for encrypted signing key (got a different banner); check you are using the private key file: %w", err)
}
return err
} Prevention
- Check the PEM BEGIN line matches the expected encrypted private key banner before calling
- Do not pass certificates or public keys where an encrypted private key is expected
- Generate keys only with nebula-cert or EncryptAndMarshalSigningPrivateKey so banners are correct
When it happens
Trigger: Calling DecryptAndUnmarshalSigningPrivateKey with a PEM block whose Type is e.g. 'CERTIFICATE', 'NEBULA X25519 PUBLIC KEY', 'OPENVPN PRIVATE KEY', or any unencrypted/foreign key banner instead of the encrypted Ed25519/ECDSA private key banner.
Common situations: Passing a certificate or public key PEM where the encrypted private key is expected, using an OpenSSL-generated key file instead of one from nebula-cert, or a key file from an older/other tool with a different banner naming.
Related errors
- input did not contain a valid PEM encoded block
- bytes did not contain a proper public key banner
- bytes did not contain a proper Ed25519/ECDSA public key bann
- ErrTruncatedPEMBlock
- unsupported encryption algorithm: %s
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/03b61c6fe6b6e42a.
Report an issue: GitHub.