hyperledger/fabric · error
channel header unmarshalling error: %s
Error message
channel header unmarshalling error: %s
What it means
ValidateConfig in orderer/consensus/smartbft/configverifier.go:79 returns "channel header unmarshalling error: %s" when protoutil.UnmarshalChannelHeader fails to decode payload.Header.ChannelHeader bytes into a common.ChannelHeader. The ChannelHeader field is non-nil but its bytes are not a valid protobuf ChannelHeader, so the validator aborts before switching on the envelope type.
Source
Thrown at orderer/consensus/smartbft/configverifier.go:79
// ValidateConfig validates config from envelope
func (cbv *ConfigBlockValidator) ValidateConfig(envelope *common.Envelope) error {
payload, err := protoutil.UnmarshalPayload(envelope.Payload)
if err != nil {
return err
}
if payload.Header == nil {
return fmt.Errorf("no header was set")
}
if payload.Header.ChannelHeader == nil {
return fmt.Errorf("no channel header was set")
}
chdr, err := protoutil.UnmarshalChannelHeader(payload.Header.ChannelHeader)
if err != nil {
return fmt.Errorf("channel header unmarshalling error: %s", err)
}
switch chdr.Type {
case int32(common.HeaderType_CONFIG):
configEnvelope := &common.ConfigEnvelope{}
if err = proto.Unmarshal(payload.Data, configEnvelope); err != nil {
return fmt.Errorf("data unmarshalling error: %s", err)
}
return cbv.verifyConfigUpdateMsg(envelope, configEnvelope, chdr)
default:
return errors.Errorf("unexpected envelope type %s", common.HeaderType_name[chdr.Type])
}
}
func (cbv *ConfigBlockValidator) checkConsentersMatchPolicy(conf *common.Config) error {
if conf == nil {
return fmt.Errorf("empty Config")
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Ensure ChannelHeader is marshaled with proto.Marshal(&common.ChannelHeader{...}) (or protoutil.MarshalOrPanic), not with another message type's bytes.
- Verify the block/envelope was not truncated or corrupted; re-fetch from a healthy orderer.
- Use protoutil.CreateSignedEnvelope instead of manual payload construction.
- Confirm client and orderer use compatible fabric-protos versions (fabric-protos-go vs fabric-protos-go-apiv2 produce identical wire format, but hand-rolled structs may not).
Example fix
// before: wrong message marshaled into the header slot
hdr := &common.Header{ChannelHeader: sighdrBytes} // SignatureHeader bytes
// after
hdr := &common.Header{
ChannelHeader: protoutil.MarshalOrPanic(&common.ChannelHeader{
Type: int32(common.HeaderType_CONFIG), ChannelId: "mychannel", Epoch: 0,
}),
} Defensive patterns
Strategy: validation
Validate before calling
chdr := &common.ChannelHeader{}
if err := proto.Unmarshal(payload.Header.ChannelHeader, chdr); err != nil {
return fmt.Errorf("client-side check: channel header bytes are not a valid ChannelHeader: %w", err)
}
if chdr.ChannelId == "" {
return errors.New("channel header has empty channel id")
} Type guard
func isWellFormedChannelHeader(b []byte) (*common.ChannelHeader, bool) {
ch := &common.ChannelHeader{}
if err := proto.Unmarshal(b, ch); err != nil || ch.ChannelId == "" {
return nil, false
}
return ch, true
} Try / catch
if err := cbv.ValidateConfig(envelope); err != nil {
if strings.Contains(err.Error(), "channel header unmarshalling error") {
return fmt.Errorf("ChannelHeader bytes corrupt: re-marshal a common.ChannelHeader")
}
return err
} Prevention
- Marshal ChannelHeader with protoutil.MarshalOrPanic(&common.ChannelHeader{...}); never paste other messages' bytes into the slot.
- Prefer protoutil.CreateSignedEnvelope to manual marshaling.
- Verify block hashes/integrity when envelopes originate from ledger data.
- Pin fabric-protos-go-apiv2 versions consistently across client and orderer.
When it happens
Trigger: An envelope whose Header.ChannelHeader contains bytes that fail proto.Unmarshal as common.ChannelHeader — e.g. random/garbage bytes, bytes from a different message type (SignatureHeader marshaled into the ChannelHeader slot), or truncation.
Common situations: Manual envelope assembly in tests/tools that marshals the wrong message into the ChannelHeader field; corrupted or tampered blocks; double-marshaling bugs in custom clients; version mismatch where a client serializes headers in an incompatible layout.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- data unmarshalling error: %s
- failed to deserialize values
- failed parsing request
- Failed unmarshalling GossipMessage from envelope: %v
- Cannot read channels list response, %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/3e4330917195c3b7.
Report an issue: GitHub.