{"record":{"id":"047a56ff91133702","repo":"hyperledger/fabric","slug":"message-is-nil","errorCode":null,"errorMessage":"message is nil","messagePattern":"message is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/deliver/binding.go","lineNumber":38,"sourceCode":"type BindingInspector func(context.Context, proto.Message) error\n\n// CertHashExtractor extracts a certificate from a proto.Message message\ntype CertHashExtractor func(proto.Message) []byte\n\n// NewBindingInspector returns a BindingInspector according to whether\n// mutualTLS is configured or not, and according to a function that extracts\n// TLS certificate hashes from proto messages\nfunc NewBindingInspector(mutualTLS bool, extractTLSCertHash CertHashExtractor) BindingInspector {\n\tif extractTLSCertHash == nil {\n\t\tpanic(errors.New(\"extractTLSCertHash parameter is nil\"))\n\t}\n\tinspectMessage := mutualTLSBinding\n\tif !mutualTLS {\n\t\tinspectMessage = noopBinding\n\t}\n\treturn func(ctx context.Context, msg proto.Message) error {\n\t\tif msg == nil {\n\t\t\treturn errors.New(\"message is nil\")\n\t\t}\n\t\treturn inspectMessage(ctx, extractTLSCertHash(msg))\n\t}\n}\n\n// mutualTLSBinding enforces the client to send its TLS cert hash in the message,\n// and then compares it to the computed hash that is derived\n// from the gRPC context.\n// In case they don't match, or the cert hash is missing from the request or\n// there is no TLS certificate to be excavated from the gRPC context,\n// an error is returned.\nfunc mutualTLSBinding(ctx context.Context, claimedTLScertHash []byte) error {\n\tif len(claimedTLScertHash) == 0 {\n\t\treturn errors.Errorf(\"client didn't include its TLS cert hash\")\n\t}\n\tactualTLScertHash := util.ExtractCertificateHashFromContext(ctx)\n\tif len(actualTLScertHash) == 0 {\n\t\treturn errors.Errorf(\"client didn't send a TLS certificate\")","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/deliver/binding.go#L20-L56","documentation":"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.","triggerScenarios":"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.","commonSituations":"Malformed client requests sending empty envelopes; server-side code paths that call the inspector without first validating the request message.","solutions":["Ensure clients send a valid non-nil Envelope in deliver/atomic broadcast requests","Validate msg != nil in the service handler before invoking the binding inspector","Check for serialization/deserialization bugs that turn messages into nil"],"exampleFix":"// before\nif err := inspector(ctx, msg); err != nil { ... }\n// after\nif msg == nil {\n    return status.Error(codes.InvalidArgument, \"empty message\")\n}\nif err := inspector(ctx, msg); err != nil { ... }","handlingStrategy":"validation","validationCode":"if msg == nil {\n    return status.Error(codes.InvalidArgument, \"empty envelope\")\n}","typeGuard":"func isValidEnvelope(msg proto.Message) bool {\n    return msg != nil && !reflect.ValueOf(msg).IsNil()\n}","tryCatchPattern":"if err := inspector(ctx, msg); err != nil {\n    if err.Error() == \"message is nil\" {\n        return status.Error(codes.InvalidArgument, err.Error())\n    }\n    return status.Error(codes.Unauthenticated, err.Error())\n}","preventionTips":["Validate incoming envelopes before binding checks","Fix client bugs that send empty messages","Add unit tests covering nil-message paths"],"tags":["grpc","mutual-tls","validation","deliver"],"backgroundTag":"nil-message","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}