hyperledger/fabric · error
config update unmarshalling error
Error message
config update unmarshalling error
What it means
Wraps a failure to unmarshal ConfigUpdateEnv.ConfigUpdate into a cb.ConfigUpdate via configtx.UnmarshalConfigUpdate inside ensureConsensusTypeChangeOnly. The ConfigUpdateEnvelope carries a ConfigUpdate field that is not a valid serialized ConfigUpdate message.
Source
Thrown at orderer/common/msgprocessor/maintenancefilter.go:176
if nextOrdererConfig.ConsensusState() != ordererConfig.ConsensusState() {
logger.Infof("[channel: %s] maintenance mode: ConsensusType.State about to change from %s to %s",
mf.support.ChannelID(), ordererConfig.ConsensusState(), nextOrdererConfig.ConsensusState())
}
return nil
}
// ensureConsensusTypeChangeOnly checks that the only change is the Channel/Orderer group, and within that,
// only to the ConsensusType value.
func (mf *MaintenanceFilter) ensureConsensusTypeChangeOnly(configEnvelope *cb.ConfigEnvelope) error {
configUpdateEnv, err := protoutil.EnvelopeToConfigUpdate(configEnvelope.LastUpdate)
if err != nil {
return errors.Wrap(err, "envelope to config update unmarshalling error")
}
configUpdate, err := configtx.UnmarshalConfigUpdate(configUpdateEnv.ConfigUpdate)
if err != nil {
return errors.Wrap(err, "config update unmarshalling error")
}
if len(configUpdate.WriteSet.Groups) == 0 {
return errors.New("config update contains no changes")
}
if len(configUpdate.WriteSet.Values) > 0 {
return errors.Errorf("config update contains changes to values in group %s", channelconfig.ChannelGroupKey)
}
if len(configUpdate.WriteSet.Groups) > 1 {
return errors.New("config update contains changes to more than one group")
}
if ordGroup, ok1 := configUpdate.WriteSet.Groups[channelconfig.OrdererGroupKey]; ok1 {
if len(ordGroup.Groups) > 0 {
return errors.Errorf("config update contains changes to groups within the %s group",
channelconfig.OrdererGroupKey)View on GitHub (pinned to 2736b63f8f)
Solutions
- Regenerate the ConfigUpdate with configtxlator compute-update from the current and desired config blocks
- Verify the ConfigUpdate field decodes cleanly before wrapping it in the envelope
- Do not hand-edit the update JSON; edit only the decoded config and recompute the delta
Defensive patterns
Strategy: validation
Validate before calling
// Go: sanity-check the ConfigUpdate bytes before wrapping
cu := &cb.ConfigUpdate{}
if err := proto.Unmarshal(cfgUpdateEnv.ConfigUpdate, cu); err != nil {
return fmt.Errorf("ConfigUpdate bytes invalid: %w", err)
} Prevention
- Use configtxlator compute-update rather than hand-building the ConfigUpdate
- Round-trip decode/encode the update JSON to catch encoding mistakes
- Keep base64 payloads intact when copying between tools
When it happens
Trigger: A config update envelope during migration whose ConfigUpdate bytes are corrupt, empty, or were re-encoded incorrectly after editing (e.g. wrong field populated, config update built by hand).
Common situations: Hand-assembling the update JSON and encoding the wrong section (encoding the whole config instead of the update), or truncating base64 during copy/paste between configtxlator steps.
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
- attempted to change consensus type from %s to %s, but next c
- attempted to change consensus type from %s to %s, transition
- failed to unmarshal BFT metadata configuration
- envelope to config update unmarshalling error
- config update contains no changes
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/d087f6c546e991e2.
Report an issue: GitHub.