hyperledger/fabric · error
unexpected envelope type %s
Error message
unexpected envelope type %s
What it means
ValidateConfig only accepts envelopes whose channel header type is HeaderType_CONFIG. Any other header type (e.g. TRANSACTION, CONFIG_UPDATE, DELIVER_SEEK_INFO) falls into the default case and is rejected with 'unexpected envelope type <name>'. This guards the SmartBFT config block validation path so only committed config blocks are processed.
Source
Thrown at orderer/consensus/smartbft/configverifier.go:90
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")
}
if conf.ChannelGroup == nil {
return fmt.Errorf("empty channel group")
}
if len(conf.ChannelGroup.Groups) == 0 {
return fmt.Errorf("no groups in channel group")
}
if conf.ChannelGroup.Groups["Orderer"] == nil {
return fmt.Errorf("no 'Orderer' group in channel groups")View on GitHub (pinned to 2736b63f8f)
Solutions
- Pass the committed CONFIG block's envelope (header type CONFIG), not the CONFIG_UPDATE submission envelope
- Verify payload.Header.ChannelHeader.Type is set to common.HeaderType_CONFIG before calling ValidateConfig
- If handling a config update submission, first run it through the orderer's broadcast/ProposeConfigUpdate flow to produce a CONFIG envelope
- Regenerate the envelope via protoutil (CreateSignedEnvelope with common.HeaderType_CONFIG) if it was built manually
Example fix
// before env.HeaderType = common.HeaderType_CONFIG_UPDATE validator.ValidateConfig(env) // -> unexpected envelope type CONFIG_UPDATE // after env.HeaderType = common.HeaderType_CONFIG validator.ValidateConfig(env) // OK
Defensive patterns
Strategy: validation
Validate before calling
func isConfigEnvelope(env *common.Envelope) bool {
payload := &common.Payload{}
if proto.Unmarshal(env.Payload, payload) != nil || payload.Header == nil {
return false
}
chdr := &common.ChannelHeader{}
if proto.Unmarshal(payload.Header.ChannelHeader, chdr) != nil {
return false
}
return chdr.Type == int32(common.HeaderType_CONFIG)
} Type guard
func guardConfigType(chdr *common.ChannelHeader) bool {
return chdr != nil && common.HeaderType(chdr.Type) == common.HeaderType_CONFIG
} Try / catch
if err := cbv.ValidateConfig(envelope); err != nil {
if strings.Contains(err.Error(), "unexpected envelope type") {
// wrong header type; route to the appropriate validator for this HeaderType
return handleNonConfigEnvelope(envelope, err)
}
return err
} Prevention
- Only feed committed config blocks (type CONFIG) into ValidateConfig
- Check ChannelHeader.Type before dispatching envelopes to validators
- Use protoutil helpers (ChannelID/UnmarshalChannelHeader) to assert type and channel before validation
- In tests, build envelopes with protoutil.CreateSignedEnvelope(common.HeaderType_CONFIG, ...)
When it happens
Trigger: Calling ConfigBlockValidator.ValidateConfig with an envelope whose ChannelHeader.Type is not int32(common.HeaderType_CONFIG) — e.g. passing a CONFIG_UPDATE transaction, an endorser transaction, or an envelope with a zero/unset (UNKNOWN) header type.
Common situations: Submitting a config update envelope (type CONFIG_UPDATE) instead of the resulting config block's envelope; feeding regular application transactions into the config validation path; constructing envelopes by hand and forgetting to set the channel header type; misconfigured deliver clients injecting non-config envelopes.
Related errors
- invalid BFT metadata configuration
- empty Config
- empty channel group
- no groups in channel group
- no 'Orderer' group in channel groups
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/600e077f5add9532.
Report an issue: GitHub.