hyperledger/fabric · error

application org %s attempted to change MSP ID from %s to %s

Error message

application org %s attempted to change MSP ID from %s to %s

What it means

Analogous to the orderer case, ValidateNew forbids changing the MSP ID of an existing application organization. If an application org keeps its name across a config update but its MSPID() changes, the update is rejected. This preserves the integrity of org identities that anchor ACL and endorsement policies on the channel.

Source

Thrown at common/channelconfig/bundle.go:132

				return errors.Errorf("orderer org %s attempted to change MSP ID from %s to %s", orgName, mspID, norg.MSPID())
			}
		}
	}

	if ac, ok := b.ApplicationConfig(); ok {
		nac, ok := nb.ApplicationConfig()
		if !ok {
			return errors.New("current config has application section, but new config does not")
		}

		for orgName, org := range ac.Organizations() {
			norg, ok := nac.Organizations()[orgName]
			if !ok {
				continue
			}
			mspID := org.MSPID()
			if mspID != norg.MSPID() {
				return errors.Errorf("application org %s attempted to change MSP ID from %s to %s", orgName, mspID, norg.MSPID())
			}
		}
	}

	if cc, ok := b.ConsortiumsConfig(); ok {
		ncc, ok := nb.ConsortiumsConfig()
		if !ok {
			return errors.Errorf("current config has consortiums section, but new config does not")
		}

		for consortiumName, consortium := range cc.Consortiums() {
			nconsortium, ok := ncc.Consortiums()[consortiumName]
			if !ok {
				continue
			}

			for orgName, org := range consortium.Organizations() {
				norg, ok := nconsortium.Organizations()[orgName]

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Keep the application org's MSP ID unchanged in the new config; diff current vs proposed config with configtxlator to confirm.
  2. If a re-keying is genuinely needed, add a new org with a new name/MSP ID, update policies/ACLs, then remove the old org in a subsequent update.
  3. Correct the typo in the org's 'ID:' field and rebuild the update transaction.
  4. Fetch the live channel config ('peer channel fetch config') and programmatically compare MSP values before submitting the update.

Example fix

// before (configtx.yaml)
- &Org1
  Name: Org1
  ID: Org1NewMSP    # changed from Org1MSP
// after
- &Org1
  Name: Org1
  ID: Org1MSP       # unchanged
Defensive patterns

Strategy: validation

Validate before calling

// Validate application org MSP IDs are preserved before proposing the update
func checkAppMSPIDs(current, proposed *cb.Config) error {
	curApp := current.Groups["Application"]
	newApp, ok := proposed.Groups["Application"]
	if curApp == nil || !ok {
		return nil
	}
	for name, old := range curApp.Groups {
		if newG, ok := newApp.Groups[name]; ok && mspIDOf(old) != mspIDOf(newG) {
			return fmt.Errorf("app org %s MSP ID would change", name)
		}
	}
	return nil
}

Type guard

func sameMSPID(a, b *cb.ConfigGroup) bool {
	return mspIDOf(a) != "" && mspIDOf(a) == mspIDOf(b)
}

Try / catch

if err := configtxManager.ProposeConfigUpdate(env); err != nil {
	if strings.Contains(err.Error(), "application org") && strings.Contains(err.Error(), "MSP ID") {
		return fmt.Errorf("revert the MSP ID change and resubmit: %w", err)
	}
	return err
}

Prevention

When it happens

Trigger: A channel config update transaction where an organization in channel->groups->Application->groups has the same name but a different MSP value (ID) than the currently committed config.

Common situations: Hand-editing an org's ID in configtx.yaml; importing a peer org from a different network with the same Name but a different MSP ID; crypto material regenerated under a different CA subject/MSP name and reflected in the config; automation scripts templating MSP IDs incorrectly.

Related errors


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