{"record":{"id":"f5a3a162d62eae6d","repo":"hyperledger/fabric","slug":"no-header-was-set","errorCode":null,"errorMessage":"no header was set","messagePattern":"no header was set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/configverifier.go","lineNumber":70,"sourceCode":"}\n\n// ConfigBlockValidator struct\ntype ConfigBlockValidator struct {\n\tConfigUpdateProposer ConfigUpdateProposer\n\tValidatingChannel    string\n\tFilters              Filters\n\tLogger               *flogging.FabricLogger\n}\n\n// ValidateConfig validates config from envelope\nfunc (cbv *ConfigBlockValidator) ValidateConfig(envelope *common.Envelope) error {\n\tpayload, err := protoutil.UnmarshalPayload(envelope.Payload)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif payload.Header == nil {\n\t\treturn fmt.Errorf(\"no header was set\")\n\t}\n\n\tif payload.Header.ChannelHeader == nil {\n\t\treturn fmt.Errorf(\"no channel header was set\")\n\t}\n\n\tchdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"channel header unmarshalling error: %s\", err)\n\t}\n\n\tswitch chdr.Type {\n\tcase int32(common.HeaderType_CONFIG):\n\t\tconfigEnvelope := &common.ConfigEnvelope{}\n\t\tif err = proto.Unmarshal(payload.Data, configEnvelope); err != nil {\n\t\t\treturn fmt.Errorf(\"data unmarshalling error: %s\", err)\n\t\t}\n\t\treturn cbv.verifyConfigUpdateMsg(envelope, configEnvelope, chdr)","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/configverifier.go#L52-L88","documentation":"ConfigBlockValidator.ValidateConfig in orderer/consensus/smartbft/configverifier.go:70 returns \"no header was set\" when the payload inside a config envelope has a nil Header field. After protoutil.UnmarshalPayload succeeds, the validator requires payload.Header (a common.Header) to be present before it can inspect the channel header. A headerless payload cannot be attributed to a channel or typed, so config validation fails immediately.","triggerScenarios":"ValidateConfig is called with an envelope whose Payload marshals successfully but carries Header == nil — e.g. an envelope constructed manually with only Payload.Data set, or a payload whose Header bytes were empty/omitted during marshaling.","commonSituations":"Hand-crafted envelopes in tests or tools that set Payload without Header; corrupted or truncated blocks read from the ledger; a custom client/SDK that builds common.Payload without populating Header; protobuf marshaling with empty-message omission producing a nil header on decode.","solutions":["Rebuild the envelope ensuring a common.Header is populated (ChannelHeader + SignatureHeader) before marshaling the payload.","Use protoutil.CreateSignedEnvelope / protoutil.MarshalOrPanic helpers so Header is always set.","Inspect the source block/transaction to confirm it was not corrupted; re-fetch or re-submit from a valid source.","Verify the client SDK version builds payloads with headers (channel header type set to CONFIG for config txs)."],"exampleFix":"// before\npayload := &common.Payload{Data: configBytes}\n// after\nchdr := &common.ChannelHeader{Type: int32(common.HeaderType_CONFIG), ChannelId: \"mychannel\"}\nsighdr := &common.SignatureHeader{Creator: creatorBytes, Nonce: nonce}\npayload := &common.Payload{\n    Header: &common.Header{ChannelHeader: protoutil.MarshalOrPanic(chdr), SignatureHeader: protoutil.MarshalOrPanic(sighdr)},\n    Data:   configBytes,\n}","handlingStrategy":"validation","validationCode":"payload, err := protoutil.UnmarshalPayload(env.Payload)\nif err != nil {\n    return fmt.Errorf(\"bad payload: %w\", err)\n}\nif payload == nil || payload.Header == nil {\n    return errors.New(\"refusing to submit: payload has no header\")\n}","typeGuard":"func hasPayloadHeader(payload *common.Payload) bool {\n    return payload != nil && payload.Header != nil\n}","tryCatchPattern":"if err := cbv.ValidateConfig(envelope); err != nil {\n    if strings.Contains(err.Error(), \"no header was set\") {\n        return fmt.Errorf(\"malformed config envelope: rebuild with protoutil.CreateSignedEnvelope\")\n    }\n    return err\n}","preventionTips":["Always build envelopes with protoutil.CreateSignedEnvelope so Header is populated.","Validate envelope structure client-side before broadcast.","Never construct common.Payload manually in production code paths.","Check ledger integrity if the envelope came from a persisted block."],"tags":["hyperledger-fabric","ordering","protobuf","envelope-validation"],"backgroundTag":"missing-message-header","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"}