{"record":{"id":"facee2881863bca2","repo":"hyperledger/fabric","slug":"could-not-unmarshall-channel-header","errorCode":null,"errorMessage":"could not unmarshall channel header","messagePattern":"could not unmarshall channel header","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/channelparticipation/validator.go","lineNumber":85,"sourceCode":"\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\n\t}\n\n\tconfigUpdate, err := configtx.UnmarshalConfigUpdate(configUpdateEnv.ConfigUpdate)\n\tif err != nil {\n\t\treturn \"\", err","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/channelparticipation/validator.go#L67-L103","documentation":"ValidateUpdateConfigEnvelope guard: protoutil.UnmarshalChannelHeader failed on payload.Header.ChannelHeader, meaning the channel header bytes are not a valid protobuf ChannelHeader message. The update-config envelope is structurally malformed.","triggerScenarios":"Sending an envelope whose ChannelHeader bytes are corrupted, mis-marshaled, or belong to a different protobuf type to the channel participation update endpoint.","commonSituations":"Mismatches between client and server protobuf definitions after a Fabric upgrade; raw byte injection from custom tooling; corrupted output of a serialization step in an intermediate proxy that rewrites envelopes.","solutions":["Re-marshal the ChannelHeader from a typed struct (cb.ChannelHeader) instead of passing arbitrary bytes.","Compare the bytes against a known-good envelope generated by configtxlator or the fabric CLI.","Align client and orderer Fabric versions so the common.ChannelHeader protobuf definition matches.","Log/decode the header locally with protoutil.UnmarshalChannelHeader to reproduce the parse failure before submitting."],"exampleFix":"// before\nhdrBytes := customSerialize(header) // not valid protobuf\n// after\nch := &cb.ChannelHeader{Type: int32(cb.HeaderType_CONFIG_UPDATE), ChannelId: \"mychannel\"}\nhdrBytes, _ := protoutil.Marshal(ch)","handlingStrategy":"validation","validationCode":"hdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)\nif err != nil { return fmt.Errorf(\"channel header not decodable: %w\", err) }","typeGuard":"func isDecodableChannelHeader(b []byte) bool {\n    _, err := protoutil.UnmarshalChannelHeader(b)\n    return err == nil\n}","tryCatchPattern":"_, err := ValidateUpdateConfigEnvelope(env)\nif err != nil && strings.Contains(err.Error(), \"could not unmarshall channel header\") {\n    // re-marshal header from a typed cb.ChannelHeader and resubmit\n}","preventionTips":["Serialize headers only via protoutil.Marshal on typed structs","Avoid proxies that transform envelope bytes mid-flight","Keep Fabric versions consistent across client and orderers","Round-trip test: marshal then unmarshal the header before sending"],"tags":["fabric","orderer","protobuf","corrupt-header"],"backgroundTag":"malformed-protobuf-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"}