slackhq/nebula · error
input did not contain a valid PEM encoded block
Error message
input did not contain a valid PEM encoded block
What it means
DecryptAndUnmarshalSigningPrivateKey calls pem.Decode on the input bytes; when no valid PEM block can be parsed (pem.Decode returns nil), it returns this error. The library requires the input to start with a PEM-encoded encrypted Nebula private key block. Any corrupted, truncated, or non-PEM input fails immediately before the key banner is even checked.
Source
Thrown at cert/crypto.go:260
return &Argon2Parameters{
version: params.Version,
Memory: params.Memory,
Parallelism: uint8(params.Parallelism),
Iterations: params.Iterations,
salt: params.Salt,
}, nil
}
// 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 {View on GitHub (pinned to dd8f660c0a)
Solutions
- Verify the input bytes actually contain a PEM block starting with '-----BEGIN NEBULA ED25519 ENCRYPTED PRIVATE KEY-----' (or the ECDSA P256 equivalent) and are not empty
- Check you are passing the encrypted private key file, not the certificate, CA file, or config file
- If the file was produced by EncryptAndMarshalSigningPrivateKey, re-export/re-copy it without text-mangling (binary/base64-safe transfer)
- Regenerate the key with nebula-cert if the source file is truly corrupt
Example fix
// before
b, _ := os.ReadFile("config.yaml") // wrong file
k, _, _, err := cert.DecryptAndUnmarshalSigningPrivateKey(pass, b)
// after
b, _ := os.ReadFile("host.key") // the encrypted Nebula private key
k, _, _, err := cert.DecryptAndUnmarshalSigningPrivateKey(pass, b) Defensive patterns
Strategy: validation
Validate before calling
func hasPEM(b []byte) bool {
blk, _ := pem.Decode(b)
return blk != nil
}
// call only if hasPEM(keyBytes) Type guard
func isValidEncryptedSigningKeyPEM(b []byte) bool {
blk, _ := pem.Decode(b)
if blk == nil {
return false
}
return blk.Type == cert.EncryptedEd25519PrivateKeyBanner || blk.Type == cert.EncryptedECDSAP256PrivateKeyBanner
} Try / catch
curve, key, rest, err := cert.DecryptAndUnmarshalSigningPrivateKey(pass, b)
if err != nil {
if strings.Contains(err.Error(), "valid PEM encoded block") {
return fmt.Errorf("key file is not PEM-encoded; check file path and contents: %w", err)
}
return err
} Prevention
- Log/inspect the first line of the key file before decrypting to confirm it is PEM
- Keep encrypted key files out of templating systems that may substitute empty values
- Transfer key files in a binary-safe way (no clipboard copy/paste)
- Write a startup check that validates all key files parse as PEM with expected banners
When it happens
Trigger: Calling DecryptAndUnmarshalSigningPrivateKey(passphrase, b) where b is not parseable as PEM: empty input, plain-text key material, a passphrase typed instead of the key file, a PEM block with invalid base64 or missing BEGIN/END lines, or output of a different function (e.g. a certificate) passed by mistake.
Common situations: Config files pointing at the wrong file (config vs key file), key files mangled by copy/paste or secret-manager templating that produced empty content, Windows line-ending or whitespace corruption, or passing an unencrypted PEM (e.g. from OpenSSL) instead of a Nebula encrypted key produced by EncryptAndMarshalSigningPrivateKey.
Related errors
- ErrTruncatedPEMBlock
- bytes did not contain a proper nebula encrypted Ed25519/ECDS
- input did not contain a valid PEM encoded block
- unsupported encryption algorithm: %s
- key was not %d bytes, is invalid ed25519 private key
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/d582036c546bae60.
Report an issue: GitHub.