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

  1. Regenerate the ConfigUpdate with configtxlator compute-update from the current and desired config blocks
  2. Verify the ConfigUpdate field decodes cleanly before wrapping it in the envelope
  3. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/d087f6c546e991e2. Report an issue: GitHub.