{"record":{"id":"3878b5ade56d7fbc","repo":"hyperledger/fabric","slug":"message-was-empty","errorCode":null,"errorMessage":"Message was empty","messagePattern":"Message was empty","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"orderer/common/msgprocessor/filter.go","lineNumber":16,"sourceCode":"/*\nCopyright IBM Corp. All Rights Reserved.\n\nSPDX-License-Identifier: Apache-2.0\n*/\n\npackage msgprocessor\n\nimport (\n\t\"errors\"\n\n\tab \"github.com/hyperledger/fabric-protos-go-apiv2/common\"\n)\n\n// ErrEmptyMessage is returned by the empty message filter on rejection.\nvar ErrEmptyMessage = errors.New(\"Message was empty\")\n\n// Rule defines a filter function which accepts, rejects, or forwards (to the next rule) an Envelope\ntype Rule interface {\n\t// Apply applies the rule to the given Envelope, either successfully or returns error\n\tApply(message *ab.Envelope) error\n}\n\n// EmptyRejectRule rejects empty messages\nvar EmptyRejectRule = Rule(emptyRejectRule{})\n\ntype emptyRejectRule struct{}\n\nfunc (a emptyRejectRule) Apply(message *ab.Envelope) error {\n\tif message.Payload == nil {\n\t\treturn ErrEmptyMessage\n\t}\n\treturn nil\n}","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/msgprocessor/filter.go#L1-L34","documentation":"ErrEmptyMessage is the sentinel returned by the emptyRejectRule, the first rule in the broadcast filter chain. Any Envelope whose Payload field is nil is rejected immediately with this error since there is nothing to process. It is the standard way the orderer signals an empty broadcast message.","triggerScenarios":"A client calls the broadcast service with an Envelope that has Payload == nil; emptyRejectRule.Apply returns ErrEmptyMessage and the transaction is rejected before any signature or ACL checks.","commonSituations":"Buggy client SDK constructing Envelope{} without setting Payload; code paths that clear the payload after signing; tests/tools submitting placeholder envelopes; network proxies stripping or failing to forward the payload bytes.","solutions":["Set the Payload on the Envelope before sending: marshal a common.Payload (header + data) and assign its bytes to envelope.Payload.","Sign the fully populated envelope client-side and verify the SDK version matches the orderer's protobuf expectations.","Add client-side validation to reject nil payloads before invoking broadcast.","If envelopes are produced by another service, log/inspect the outgoing bytes to find where the payload is dropped."],"exampleFix":"// before\nenv := &common.Envelope{Signature: sig}        // Payload never set\n// after\npayloadBytes, _ := proto.Marshal(payload)\nenv := &common.Envelope{Payload: payloadBytes, Signature: sig}","handlingStrategy":"validation","validationCode":"if env.Payload == nil || len(env.Payload) == 0 { return errors.New(\"cannot broadcast: envelope payload is empty\") }","typeGuard":null,"tryCatchPattern":"if err := broadcast.Send(env); err != nil && errors.Is(err, msgprocessor.ErrEmptyMessage) { construct and attach a valid Payload before retrying }","preventionTips":["Always build Envelope via SDK helpers that set Payload and Signature together","Assert payload non-nil in client code before send","Compare SDK and orderer protobuf versions","Integration-test broadcast with a real transaction payload"],"tags":["orderer","fabric","broadcast","validation"],"backgroundTag":"empty-message-payload","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"}