slackhq/nebula · error
encoded Details was nil
Error message
encoded Details was nil
What it means
After protobuf unmarshaling, the RawNebulaCertificate must contain a Details message; a nil Details means the serialized certificate lacks the required details payload (name, networks, ips, etc.), which is invalid for a v1 nebula certificate.
Source
Thrown at cert/cert_v1.go:413
}
c.signature = b
return nil
}
// unmarshalCertificateV1 will unmarshal a protobuf byte representation of a nebula cert
// if the publicKey is provided here then it is not required to be present in `b`
func unmarshalCertificateV1(b []byte, publicKey []byte) (*certificateV1, error) {
if len(b) == 0 {
return nil, fmt.Errorf("nil byte array")
}
var rc RawNebulaCertificate
err := proto.Unmarshal(b, &rc)
if err != nil {
return nil, err
}
if rc.Details == nil {
return nil, fmt.Errorf("encoded Details was nil")
}
if len(rc.Details.Ips)%2 != 0 {
return nil, fmt.Errorf("encoded IPs should be in pairs, an odd number was found")
}
if len(rc.Details.Subnets)%2 != 0 {
return nil, fmt.Errorf("encoded Subnets should be in pairs, an odd number was found")
}
nc := certificateV1{
details: detailsV1{
name: rc.Details.Name,
groups: make([]string, len(rc.Details.Groups)),
networks: make([]netip.Prefix, len(rc.Details.Ips)/2),
unsafeNetworks: make([]netip.Prefix, len(rc.Details.Subnets)/2),
notBefore: time.Unix(rc.Details.NotBefore, 0),
notAfter: time.Unix(rc.Details.NotAfter, 0),View on GitHub (pinned to dd8f660c0a)
Solutions
- Ensure the certificate is marshaled with Details populated (marshal via the library's Marshal, not by hand)
- Validate the certificate source; re-read or re-issue the certificate
- Check for corruption in transport/storage of the certificate bytes
- Inspect the raw protobuf (e.g. protoc --decode) to confirm Details is present
Example fix
// before
bad := &cert.RawNebulaCertificate{Version: 1}
b, _ := proto.Marshal(bad) // Details nil
unmarshalCertificateV1(b, nil)
// after
good, _ := someCert.Marshal() // includes Details
unmarshalCertificateV1(good, nil) Defensive patterns
Strategy: try-catch
Try / catch
c, err := unmarshalCertificateV1(b, nil)
if err != nil {
if strings.Contains(err.Error(), "encoded Details was nil") {
return nil, fmt.Errorf("certificate bytes are malformed (missing Details); re-issue or re-read the cert")
}
return nil, err
} Prevention
- Always marshal certificates with the library's Marshal, never by hand-assembling protobufs
- Validate certificate data integrity (hashes/signatures) in transit and at rest
- Never mutate RawNebulaCertificate fields directly after unmarshal
- Re-issue certificates that fail to round-trip marshal/unmarshal
When it happens
Trigger: unmarshalCertificateV1 receives bytes that decode to a RawNebulaCertificate with rc.Details == nil — e.g. an empty or hand-crafted protobuf message, or data corrupted so the Details submessage was dropped.
Common situations: Manually constructing or mutating RawNebulaCertificate without populating Details; truncation/corruption in transit; writing a certificate with only the version field set; test fixtures with minimal protobufs.
Related errors
- nil byte array
- encoded IPs should be in pairs, an odd number was found
- encoded Subnets should be in pairs, an odd number was found
- encoded EncryptionMetadata was nil
- encoded Argon2Parameters was nil
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/4df0f730d37bbba4.
Report an issue: GitHub.