{"record":{"id":"0e21702ceddcc6bb","repo":"hyperledger/fabric","slug":"bad-header","errorCode":null,"errorMessage":"bad header","messagePattern":"bad header","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/channelparticipation/validator.go","lineNumber":80,"sourceCode":"\t\treturn \"\", errors.New(\"invalid config: must contain application config\")\n\t}\n\n\treturn channelID, err\n}\n\n// ValidateUpdateConfigEnvelope checks whether this envelope can be used as an update config for the channel participation API.\n// It returns the channel ID.\n// It verifies that it is not a system channel by checking that consortiums config does not exist.\n// It verifies it is an application channel by checking that the application group exists.\n// It returns an error when it cannot be used as a update config envelope.\nfunc ValidateUpdateConfigEnvelope(env *cb.Envelope) (channelID string, err error) {\n\tpayload, err := protoutil.UnmarshalPayload(env.Payload)\n\tif err != nil {\n\t\treturn \"\", errors.New(\"bad payload\")\n\t}\n\n\tif payload.Header == nil || payload.Header.ChannelHeader == nil {\n\t\treturn \"\", errors.New(\"bad header\")\n\t}\n\n\tch, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)\n\tif err != nil {\n\t\treturn \"\", errors.New(\"could not unmarshall channel header\")\n\t}\n\n\tif ch.Type != int32(cb.HeaderType_CONFIG_UPDATE) {\n\t\treturn \"\", errors.New(\"bad type\")\n\t}\n\n\tif ch.ChannelId == \"\" {\n\t\treturn \"\", errors.New(\"empty channel id\")\n\t}\n\n\tconfigUpdateEnv, err := protoutil.EnvelopeToConfigUpdate(env)\n\tif err != nil {\n\t\treturn \"\", err","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/channelparticipation/validator.go#L62-L98","documentation":"After the payload unmarshals, ValidateUpdateConfigEnvelope requires payload.Header and payload.Header.ChannelHeader to be present. This error is returned when either is nil, meaning the envelope lacks the metadata needed to identify the channel and message type.","triggerScenarios":"Submitting a config-update envelope constructed without a ChannelHeader (or with no Header at all) to the channel participation update endpoint.","commonSituations":"Hand-built envelopes missing the Header field; SDK calls that set Data but skip channel headers; copy-pasted envelope-construction code that populates only Payload.Data.","solutions":["Build the header with protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, version, channelID, epoch) and attach it via protoutil.MakePayloadHeader before marshaling the payload.","Verify with 'configtxlator' or a small Go snippet that payload.Header.ChannelHeader is non-nil and decodable.","Use an SDK or fabric CLI code path (e.g. channel update flow) that populates headers automatically instead of hand-crafting envelopes.","Re-generate the config update from the current channel config rather than reusing a stripped-down envelope."],"exampleFix":"// before\npayload := &cb.Payload{Data: data} // no header\n// after\nchHdr := protoutil.MakeChannelHeader(cb.HeaderType_CONFIG_UPDATE, int32(1), \"mychannel\", 0)\npayload := &cb.Payload{Header: protoutil.MakePayloadHeader(chHdr, sigHdr), Data: data}","handlingStrategy":"validation","validationCode":"p, err := protoutil.UnmarshalPayload(env.Payload)\nif err != nil { return err }\nif p.Header == nil || p.Header.ChannelHeader == nil {\n    return errors.New(\"payload must carry a ChannelHeader\")\n}","typeGuard":"func hasChannelHeader(env *cb.Envelope) bool {\n    p, err := protoutil.UnmarshalPayload(env.Payload)\n    if err != nil || p.Header == nil { return false }\n    return p.Header.ChannelHeader != nil\n}","tryCatchPattern":"if _, err := ValidateUpdateConfigEnvelope(env); err != nil && strings.Contains(err.Error(), \"bad header\") {\n    // rebuild payload with protoutil.MakePayloadHeader\n}","preventionTips":["Use protoutil.MakeChannelHeader + MakePayloadHeader to always attach headers","Never hand-strip header fields when copying envelope-construction code","Decode and inspect envelopes with configtxlator before submission","Add a unit test asserting the submitted envelope contains a ChannelHeader"],"tags":["fabric","orderer","missing-header","protobuf"],"backgroundTag":"missing-protobuf-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"}