{"record":{"id":"5ca83b2c831e0856","repo":"hyperledger/fabric","slug":"missing-channel-header-5ca83b","errorCode":null,"errorMessage":"missing channel header","messagePattern":"missing channel header","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/common/multichannel/registrar.go","lineNumber":371,"sourceCode":"\treturn r.chains[chainID]\n}\n\n// GetFollower retrieves the follower.Chain if it exists.\nfunc (r *Registrar) GetFollower(chainID string) *follower.Chain {\n\tr.lock.RLock()\n\tdefer r.lock.RUnlock()\n\n\treturn r.followers[chainID]\n}\n\nfunc (r *Registrar) newLedgerResources(configTx *cb.Envelope) (*ledgerResources, error) {\n\tpayload, err := protoutil.UnmarshalPayload(configTx.Payload)\n\tif err != nil {\n\t\treturn nil, errors.WithMessage(err, \"error umarshaling envelope to payload\")\n\t}\n\n\tif payload.Header == nil {\n\t\treturn nil, errors.New(\"missing channel header\")\n\t}\n\n\tchdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)\n\tif err != nil {\n\t\treturn nil, errors.WithMessage(err, \"error unmarshalling channel header\")\n\t}\n\n\tconfigEnvelope, err := configtx.UnmarshalConfigEnvelope(payload.Data)\n\tif err != nil {\n\t\treturn nil, errors.WithMessage(err, \"error umarshaling config envelope from payload data\")\n\t}\n\n\tbundle, err := channelconfig.NewBundle(chdr.ChannelId, configEnvelope.Config, r.bccsp)\n\tif err != nil {\n\t\treturn nil, errors.WithMessage(err, \"error creating channelconfig bundle\")\n\t}\n\n\terr = checkResources(bundle)","sourceCodeStart":353,"sourceCodeEnd":389,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/common/multichannel/registrar.go#L353-L389","documentation":"The orderer's multichannel registrar, while building ledger resources for a channel from a config transaction envelope, found that the envelope's payload had no header. Fabric envelopes must carry a ChannelHeader identifying the channel and tx type; without it the registrar cannot determine which channel the config belongs to and aborts chain initialization.","triggerScenarios":"initAppChannels / initLedgerResourcesClusterConsenter / createNewChannel are handed a malformed config envelope whose payload.Header is nil — typically a corrupted or hand-crafted config transaction submitted via Broadcast, or a genesis/join block whose payload did not deserialize with a header.","commonSituations":"Submitting a manually assembled envelope (marshaled common.Payload without Header set), a truncated/corrupted block file or on-disk ledger entry, or a bug in a client SDK building config update transactions.","solutions":["Regenerate the config transaction/genesis block with configtxgen or the configtxlator instead of hand-crafting the envelope","Verify the envelope was built with protoutil.CreateSignedEnvelope so the payload header is populated","Inspect the offending block/ledger data for corruption and rebuild the orderer ledger (wipe data dir and re-join with a valid genesis/join block)","Check client SDK version for known envelope-marshaling bugs and upgrade"],"exampleFix":"// before: manual envelope with no header\npayload := &common.Payload{Data: configData}\nraw, _ := proto.Marshal(payload)\n\n// after: use the helper that sets the header\nenv, err := protoutil.CreateSignedEnvelope(common.HeaderType_CONFIG, \"mychannel\", nil, configUpdate, 0, 0)","handlingStrategy":"validation","validationCode":"// Go: validate envelope before broadcast/submit\npayload, err := protoutil.UnmarshalPayload(env.Payload)\nif err != nil { return err }\nif payload.Header == nil || len(payload.Header.ChannelHeader) == 0 {\n    return errors.New(\"envelope has no channel header\")\n}\nif _, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader); err != nil { return err }","typeGuard":"func hasChannelHeader(p *common.Payload) bool {\n    return p != nil && p.Header != nil && len(p.Header.ChannelHeader) > 0\n}","tryCatchPattern":"if err := validateEnvelope(env); err != nil {\n    // don't broadcast; log and resubmit a properly built envelope\n    logger.Errorf(\"skipping malformed envelope: %v\", err)\n    return err\n}","preventionTips":["Always build envelopes with protoutil.CreateSignedEnvelope instead of marshaling raw Payload structs","Unit-test generated envelopes with protoutil.UnmarshalPayload + UnmarshalChannelHeader before shipping","Hash-verify block files used as ledger/join input to catch corruption"],"tags":["hyperledger-fabric","orderer","envelope","malformed-input"],"backgroundTag":"missing-payload-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"}