slackhq/nebula · error

ErrNoPayload

ErrNoPayload

Error message

provided payload was empty

What it means

ErrNoPayload is returned by Recombine when the rawCertBytes argument is nil. The raw certificate bytes are the payload being recombined; an empty payload gives Recombine nothing to work with, so it fails immediately.

Source

Thrown at cert/errors.go:35

	ErrInvalidPublicKey           = errors.New("invalid public key")
	ErrInvalidPrivateKey          = errors.New("invalid private key")
	ErrPublicPrivateCurveMismatch = errors.New("public key does not match private key curve")
	ErrPublicPrivateKeyMismatch   = errors.New("public key and private key are not a pair")
	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

  1. Verify rawCertBytes is non-nil before calling Recombine
  2. Check that the earlier Marshal/MarshalForHandshakes call succeeded and its output was stored
  3. Log/handle empty handshake certificate payloads on the wire before recombining

Example fix

// before
cert, err := Recombine(v, raw, pub, curve) // raw == nil
// after
if len(raw) == 0 {
    return nil, fmt.Errorf("empty certificate payload")
}
cert, err := Recombine(v, raw, pub, curve)
Defensive patterns

Strategy: validation

Validate before calling

if len(rawCertBytes) == 0 {
    return fmt.Errorf("empty certificate payload; cannot Recombine")
}

Type guard

func hasPayload(b []byte) bool { return len(b) > 0 }

Try / catch

c, err := cert.Recombine(v, raw, pub, curve)
if errors.Is(err, cert.ErrNoPayload) {
    // drop/handle empty cert frame from peer
}

Prevention

When it happens

Trigger: Calling cert.Recombine(version, nil, publicKey, curve) — the raw certificate byte slice is nil, e.g. when upstream marshalling failed silently or the handshake frame had no cert field.

Common situations: Handshake message received without the certificate payload; a previous Marshal/MarshalForHandshakes error swallowed and nil propagated; peer sending an empty certificate frame.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/1be0ad333b346969. Report an issue: GitHub.