slackhq/nebula · error
bytes did not contain a proper public key banner
Error message
bytes did not contain a proper public key banner
What it means
The PEM block decoded successfully but its Type banner is not X25519PublicKeyBanner or P256PublicKeyBanner, the only banners UnmarshalPublicKeyFromPEM accepts (ECDH key-agreement keys). The function deliberately rejects signing-key banners and suggests UnmarshalSigningPublicKeyFromPEM for those.
Source
Thrown at cert/pem.go:170
// consumed data or an error on failure. Only key-agreement (ECDH) public key banners are accepted.
// Use UnmarshalSigningPublicKeyFromPEM for Ed25519/ECDSA banners.
func UnmarshalPublicKeyFromPEM(b []byte) ([]byte, []byte, Curve, error) {
k, r := pem.Decode(b)
if k == nil {
return nil, r, 0, fmt.Errorf("input did not contain a valid PEM encoded block")
}
var expectedLen int
var curve Curve
switch k.Type {
case X25519PublicKeyBanner:
expectedLen = 32
curve = Curve_CURVE25519
case P256PublicKeyBanner:
// Uncompressed
expectedLen = 65
curve = Curve_P256
default:
return nil, r, 0, fmt.Errorf("bytes did not contain a proper public key banner")
}
if len(k.Bytes) != expectedLen {
return nil, r, 0, fmt.Errorf("key was not %d bytes, is invalid %s public key", expectedLen, curve)
}
return k.Bytes, r, curve, nil
}
// UnmarshalSigningPublicKeyFromPEM will try to unmarshal the first pem block in a byte array, returning any non
// consumed data or an error on failure. Only Ed25519/ECDSA public key banners are accepted.
// Use UnmarshalPublicKeyFromPEM for X25519/P256 (ECDH) banners.
func UnmarshalSigningPublicKeyFromPEM(b []byte) ([]byte, []byte, Curve, error) {
k, r := pem.Decode(b)
if k == nil {
return nil, r, 0, fmt.Errorf("input did not contain a valid PEM encoded block")
}
var expectedLen int
var curve Curve
switch k.Type {View on GitHub (pinned to dd8f660c0a)
Solutions
- Use UnmarshalSigningPublicKeyFromPEM if the PEM type is an Ed25519/ECDSA signing public key banner
- Ensure the input is an ECDH public key: '-----BEGIN NEBULA X25519 PUBLIC KEY-----' or '-----BEGIN NEBULA ECDSA P256 PUBLIC KEY-----'
- Extract the correct key type from the certificate via the appropriate API rather than feeding the whole certificate PEM to this function
Example fix
// before _, rest, curve, err := cert.UnmarshalPublicKeyFromPEM(ed25519PubPEM) // signing key banner // after _, rest, curve, err := cert.UnmarshalSigningPublicKeyFromPEM(ed25519PubPEM)
Defensive patterns
Strategy: validation
Validate before calling
func isECDHBanner(b []byte) bool {
blk, _ := pem.Decode(b)
if blk == nil {
return false
}
return blk.Type == cert.X25519PublicKeyBanner || blk.Type == cert.P256PublicKeyBanner
} Try / catch
pub, rest, curve, err := cert.UnmarshalPublicKeyFromPEM(b)
if err != nil {
if strings.Contains(err.Error(), "proper public key banner") {
if blk, _ := pem.Decode(b); blk != nil && (blk.Type == cert.Ed25519PublicKeyBanner || blk.Type == cert.ECDSAP256PublicKeyBanner) {
_, _, _, err = cert.UnmarshalSigningPublicKeyFromPEM(b)
return err
}
}
return err
} Prevention
- Track which key type (signing vs encryption) each file/field holds; name files accordingly (host.key vs host.pub)
- Route Ed25519/ECDSA signing banners to UnmarshalSigningPublicKeyFromPEM instead
- Do not pass certificate PEM blocks to public-key unmarshal functions
When it happens
Trigger: Calling UnmarshalPublicKeyFromPEM with a PEM block typed e.g. 'NEBULA ED25519 PUBLIC KEY', 'CERTIFICATE', or 'NEBULA ED25519 ENCRYPTED PRIVATE KEY' instead of an X25519/P256 public key banner.
Common situations: Mixing up signing keys and encryption keys in Nebula configs — trying to load a node's Ed25519 signing public key (or a certificate) where the X25519 ECDH public key is required, often when populating static_host_map or firewall keys.
Related errors
- bytes did not contain a proper Ed25519/ECDSA public key bann
- bytes did not contain a proper nebula encrypted Ed25519/ECDS
- input did not contain a valid PEM encoded block
- key was not %d bytes, is invalid %s public key
- ErrTruncatedPEMBlock
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/2303b1c6dd477b00.
Report an issue: GitHub.