hyperledger/fabric · error

new channel has consenter that is not part of system consent

Error message

new channel has consenter that is not part of system consenter set

What it means

During creation of a new application channel (newChannel=true), the etcdraft consenter set must be a subset of the system channel's consenters (orderer/consensus/etcdraft/chain.go:1519). This error means the new channel's raft metadata contains a consenter (host/port) that is not present in the old (system channel) metadata set. It is a hard check in VerifyConfigMetadata, not a transient failure.

Source

Thrown at orderer/consensus/etcdraft/chain.go:1519

	if err := proto.Unmarshal(newOrdererConfig.ConsensusMetadata(), newMetadata); err != nil {
		return errors.Wrap(err, "failed to unmarshal new etcdraft metadata configuration")
	}

	verifyOpts, err := createX509VerifyOptions(newOrdererConfig)
	if err != nil {
		return errors.Wrapf(err, "failed to create x509 verify options from old and new orderer config")
	}

	if err := VerifyConfigMetadata(newMetadata, verifyOpts); err != nil {
		return errors.Wrap(err, "invalid new config metadata")
	}

	if newChannel {
		// check if the consenters are a subset of the existing consenters (system channel consenters)
		set := ConsentersToMap(oldMetadata.GetConsenters())
		for _, c := range newMetadata.GetConsenters() {
			if !set.Exists(c) {
				return errors.New("new channel has consenter that is not part of system consenter set")
			}
		}
		return nil
	}

	// create the dummy parameters for ComputeMembershipChanges
	c.raftMetadataLock.RLock()
	dummyOldBlockMetadata := proto.Clone(c.opts.BlockMetadata).(*etcdraft.BlockMetadata)
	c.raftMetadataLock.RUnlock()

	dummyOldConsentersMap := CreateConsentersMap(dummyOldBlockMetadata, oldMetadata)
	changes, err := ComputeMembershipChanges(dummyOldBlockMetadata, dummyOldConsentersMap, newMetadata.GetConsenters())
	if err != nil {
		return err
	}

	// new config metadata was verified above. Additionally need to check new consenters for certificates expiration
	for _, c := range changes.AddedNodes {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Add the missing consenter to the system channel first, wait for its block/certificates to be committed, then create the channel
  2. Remove the extraneous consenter from the new channel's configtx profile
  3. Compare host:port strings exactly (including port) with the system channel consenters

Example fix

// before (new channel profile)
Consenters: [{Host: orderer3.example.com, Port: 7050}] // not in system channel
// after
Consenters: [{Host: orderer1.example.com, Port: 7050}, {Host: orderer2.example.com, Port: 7050}] // subset of system channel consenters
Defensive patterns

Strategy: validation

Validate before calling

sysSet := ConsentersToMap(systemChannelMetadata.GetConsenters())
for _, c := range newChannelMetadata.GetConsenters() {
    if !sysSet.Exists(c) {
        return fmt.Errorf("consenter %s:%d must first be added to the system channel", c.GetHost(), c.GetPort())
    }
}

Type guard

func subsetOfSystem(new, sys []*common.Consenter) bool {
    set := ConsentersToMap(sys)
    for _, c := range new {
        if !set.Exists(c) { return false }
    }
    return true
}

Prevention

When it happens

Trigger: A channel creation request whose etcdraft ConfigMetadata lists a consenter with a host:port combination absent from the system channel's consenters.

Common situations: Hand-editing the channel creation profile to add an extra orderer before it was added to the system channel; typos in host or port differing from the system channel entry; Fabric migration flows where the new profile was generated from a stale system channel config.

Related errors


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