hyperledger/fabric · error
config update contains changes to values in group %s
Error message
config update contains changes to values in group %s
What it means
Returned when the config update's WriteSet contains changes to values directly in the top-level Channel group (channelconfig.ChannelGroupKey). The maintenance filter only permits changes inside the Orderer group's ConsensusType value, so any value-level change at the Channel group is rejected.
Source
Thrown at orderer/common/msgprocessor/maintenancefilter.go:184
// 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)
}
if _, ok2 := ordGroup.Values[channelconfig.ConsensusTypeKey]; !ok2 {
return errors.Errorf("config update does not contain the %s value", channelconfig.ConsensusTypeKey)
}
if len(ordGroup.Values) > 1 {
return errors.Errorf("config update contain more then just the %s value in the %s group",View on GitHub (pinned to 2736b63f8f)
Solutions
- Remove all top-level Channel-group value changes from the update; keep only the Orderer group ConsensusType change
- Submit separate config updates: do non-migration value changes before entering maintenance mode or after the migration completes
- Recompute the delta so the write set contains only Groups[orderer].Values[ConsensusType]
Example fix
// before: bundled changes
WriteSet: { Values: { Capabilities: ... }, Groups: { Orderer: { Values: { ConsensusType: ... } } } }
// after: only the consensus type change
WriteSet: { Values: {}, Groups: { Orderer: { Values: { ConsensusType: { State: STATE_MAINTENANCE, Type: "BFT" } } } } } Defensive patterns
Strategy: validation
Validate before calling
if len(update.WriteSet.Values) > 0 {
return errors.New("update must not change Channel-group values during consensus migration")
} Prevention
- Keep migration updates limited to Orderer/ConsensusType only
- Schedule other config value changes before entering or after leaving maintenance
- Review the configtxlator delta output for unexpected Values entries before signing
When it happens
Trigger: A maintenance-mode config update whose WriteSet.Values is non-empty, e.g. bundling a change to a Channel-group config value (like BlockValidation or capabilities) together with the consensus type change.
Common situations: Administrators trying to batch multiple config changes (capabilities upgrade plus consensus migration) into a single update while the channel is in maintenance mode.
Related errors
- config update contains no changes
- config update contains changes to more than one group
- 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
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/145cf8bb4fae0387.
Report an issue: GitHub.