hyperledger/fabric · error

message is nil

Error message

message is nil

What it means

The binding inspector returned by NewBindingInspector requires a non-nil proto.Message to extract the TLS cert hash from. A nil message means nothing can be inspected, so the request is rejected immediately.

Source

Thrown at common/deliver/binding.go:38

type BindingInspector func(context.Context, proto.Message) error

// CertHashExtractor extracts a certificate from a proto.Message message
type CertHashExtractor func(proto.Message) []byte

// NewBindingInspector returns a BindingInspector according to whether
// mutualTLS is configured or not, and according to a function that extracts
// TLS certificate hashes from proto messages
func NewBindingInspector(mutualTLS bool, extractTLSCertHash CertHashExtractor) BindingInspector {
	if extractTLSCertHash == nil {
		panic(errors.New("extractTLSCertHash parameter is nil"))
	}
	inspectMessage := mutualTLSBinding
	if !mutualTLS {
		inspectMessage = noopBinding
	}
	return func(ctx context.Context, msg proto.Message) error {
		if msg == nil {
			return errors.New("message is nil")
		}
		return inspectMessage(ctx, extractTLSCertHash(msg))
	}
}

// mutualTLSBinding enforces the client to send its TLS cert hash in the message,
// and then compares it to the computed hash that is derived
// from the gRPC context.
// In case they don't match, or the cert hash is missing from the request or
// there is no TLS certificate to be excavated from the gRPC context,
// an error is returned.
func mutualTLSBinding(ctx context.Context, claimedTLScertHash []byte) error {
	if len(claimedTLScertHash) == 0 {
		return errors.Errorf("client didn't include its TLS cert hash")
	}
	actualTLScertHash := util.ExtractCertificateHashFromContext(ctx)
	if len(actualTLScertHash) == 0 {
		return errors.Errorf("client didn't send a TLS certificate")

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure clients send a valid non-nil Envelope in deliver/atomic broadcast requests
  2. Validate msg != nil in the service handler before invoking the binding inspector
  3. Check for serialization/deserialization bugs that turn messages into nil

Example fix

// before
if err := inspector(ctx, msg); err != nil { ... }
// after
if msg == nil {
    return status.Error(codes.InvalidArgument, "empty message")
}
if err := inspector(ctx, msg); err != nil { ... }
Defensive patterns

Strategy: validation

Validate before calling

if msg == nil {
    return status.Error(codes.InvalidArgument, "empty envelope")
}

Type guard

func isValidEnvelope(msg proto.Message) bool {
    return msg != nil && !reflect.ValueOf(msg).IsNil()
}

Try / catch

if err := inspector(ctx, msg); err != nil {
    if err.Error() == "message is nil" {
        return status.Error(codes.InvalidArgument, err.Error())
    }
    return status.Error(codes.Unauthenticated, err.Error())
}

Prevention

When it happens

Trigger: Invoking the returned binding inspector function with msg == nil, e.g., when a gRPC stream delivers a nil envelope or the caller passes nil to the binding check.

Common situations: Malformed client requests sending empty envelopes; server-side code paths that call the inspector without first validating the request message.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/047a56ff91133702. Report an issue: GitHub.