hyperledger/fabric · error
proto: Marshal called with nil
Error message
proto: Marshal called with nil
What it means
SignSecret returns this error when the given *gossip.Secret is nil, mirroring the message protobuf's Marshal would emit. It short-circuits before proto.Marshal to avoid a panic/nil error deeper in serialization.
Source
Thrown at gossip/protoext/signing.go:28
"errors"
"fmt"
"github.com/hyperledger/fabric-protos-go-apiv2/gossip"
"google.golang.org/protobuf/proto"
)
// Signer signs a message, and returns (signature, nil)
// on success, and nil and an error on failure.
type Signer func(msg []byte) ([]byte, error)
// Verifier receives a peer identity, a signature and a message and returns nil
// if the signature on the message could be verified using the given identity.
type Verifier func(peerIdentity []byte, signature, message []byte) error
// SignSecret signs the secret payload and creates a secret envelope out of it.
func SignSecret(e *gossip.Envelope, signer Signer, secret *gossip.Secret) error {
if secret == nil {
return errors.New("proto: Marshal called with nil")
}
payload, err := proto.Marshal(secret)
if err != nil {
return err
}
sig, err := signer(payload)
if err != nil {
return err
}
e.SecretEnvelope = &gossip.SecretEnvelope{
Payload: payload,
Signature: sig,
}
return nil
}
// NoopSign creates a SignedGossipMessage with a nil signature
func NoopSign(m *gossip.GossipMessage) (*SignedGossipMessage, error) {View on GitHub (pinned to 2736b63f8f)
Solutions
- Pass a non-nil gossip.Secret to SignSecret, or skip signing entirely when no secret exists
- Check the upstream code path that produced the Secret and fix the nil assignment
- Guard the call site: only call SignSecret when a secret is required and present
Example fix
// before
protoext.SignSecret(envelope, signer, secret) // secret may be nil
// after
if secret != nil {
err := protoext.SignSecret(envelope, signer, secret)
} Defensive patterns
Strategy: type-guard
Validate before calling
if secret == nil {
return nil // nothing to sign; skip SignSecret
} Type guard
func hasSecret(s *gossip.Secret) bool { return s != nil } Try / catch
if err := protoext.SignSecret(env, signer, secret); err != nil {
if err.Error() == "proto: Marshal called with nil" {
return fmt.Errorf("no secret provided to sign: %w", err)
}
return err
} Prevention
- Only call SignSecret when the envelope actually carries a secret
- Check the Secret extraction/parse step for nil returns
- Add a unit test covering the nil-secret call
When it happens
Trigger: Calling SignSecret(e, signer, nil) — e.g. an envelope that has no SecretEnvelope content to attach, or a caller passing a nil secret extracted from a failed parse.
Common situations: Building authenticated gossip envelopes where the secret (e.g. internal endpoint) is absent; refactoring code that changed when secrets are populated; tests passing nil for brevity.
Related errors
- nil envelope
- error marshaling
- error decoding the block number
- error decoding the data hash
- error decoding the previous hash
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/745f6d20ac29d457.
Report an issue: GitHub.