slackhq/nebula · error
ErrEmptyRawDetails
ErrEmptyRawDetails
Error message
empty rawDetails not allowed
What it means
ErrEmptyRawDetails is returned by certificateV2's Marshal and MarshalForHandshakes when rawDetails is nil. Marshalling serializes the stored raw details into the wire format; without them there is nothing to encode, so both methods fail fast.
Source
Thrown at cert/errors.go:39
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...)}
}
func (e *ErrInvalidCertificateProperties) Error() string {
return e.str
}
View on GitHub (pinned to dd8f660c0a)
Solutions
- Populate rawDetails (e.g. via details.Marshal() or the normal construction path) before calling Marshal/MarshalForHandshakes
- Check that the certificate was built through the library constructor rather than as a bare struct literal
- Validate the source certificate bytes were parsed completely before marshalling
Example fix
// before
c := &certificateV2{}
b, err := c.Marshal() // rawDetails nil
// after
rd, err := c.details.Marshal()
c.rawDetails = rd
b, err := c.Marshal() Defensive patterns
Strategy: validation
Validate before calling
if c.rawDetails == nil {
return fmt.Errorf("certificate not initialized: rawDetails missing")
} Type guard
func marshalable(c *cert.CertificateV2) bool {
_, err := c.Marshal()
return err == nil
} Try / catch
b, err := c.MarshalForHandshakes()
if errors.Is(err, cert.ErrEmptyRawDetails) {
// certificate was never populated; rebuild from source
} Prevention
- Never construct certificateV2 as a zero-value literal for real use
- Populate rawDetails via the details marshal path before any serialization
- Validate deserialized certificates immediately after parsing
When it happens
Trigger: Calling MarshalForHandshakes() or Marshal() on a certificateV2 whose rawDetails is nil — e.g. a zero-value certificate, or one deserialized from input lacking the details section.
Common situations: Constructing a certificateV2 by hand in tests/tools without setting rawDetails; truncated or corrupt certificate bytes dropping the details field; calling Marshal before the certificate is fully initialized.
Related errors
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/5095a546d85df291.
Report an issue: GitHub.