hyperledger/fabric · error

Attempted to define two different versions of MSP: %s

Error message

Attempted to define two different versions of MSP: %s

What it means

ProposeMSP tracks pending MSPs by identifier in bh.idMap. If an MSP with the same ID already exists in the pending set but its proto config differs from the new one, it rejects with 'Attempted to define two different versions of MSP: %s'. This prevents a config update from redefining an existing MSP with different material under the same identity.

Source

Thrown at common/channelconfig/msp.go:85

		if err != nil {
			return nil, errors.WithMessage(err, "creating the MSP manager failed")
		}
	default:
		return nil, errors.New(fmt.Sprintf("Setup error: unsupported msp type %d", mspConfig.Type))
	}

	// set it up
	err = theMsp.Setup(mspConfig)
	if err != nil {
		return nil, errors.WithMessage(err, "setting up the MSP manager failed")
	}

	// add the MSP to the map of pending MSPs
	mspID, _ := theMsp.GetIdentifier()

	existingPendingMSPConfig, ok := bh.idMap[mspID]
	if ok && !proto.Equal(existingPendingMSPConfig.mspConfig, mspConfig) {
		return nil, errors.New(fmt.Sprintf("Attempted to define two different versions of MSP: %s", mspID))
	}

	if !ok {
		bh.idMap[mspID] = &pendingMSPConfig{
			mspConfig: mspConfig,
			msp:       theMsp,
		}
	}

	return theMsp, nil
}

func (bh *MSPConfigHandler) CreateMSPManager() (msp.MSPManager, error) {
	mspList := make([]msp.MSP, len(bh.idMap))
	i := 0
	for _, pendingMSP := range bh.idMap {
		mspList[i] = pendingMSP.msp
		i++

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure each MSP ID appears exactly once in the config; remove duplicate org/MSP entries
  2. For cert rotation, replace the existing MSP config atomically rather than adding a second definition with the same ID
  3. Use configtxlator to diff the current and updated config and find the MSP defined twice
  4. If the MSPs truly are identical, ensure the bytes match exactly — different serialization of equal material still triggers this

Example fix

// before: two orgs with same MSP ID but different certs
organizations:
  Org1:
    MSPId: Org1MSP
    ...certs-v1...
  Org1New:
    MSPId: Org1MSP
    ...certs-v2...
// after: one definition, one MSP ID
organizations:
  Org1:
    MSPId: Org1MSP
    ...updated-certs...
Defensive patterns

Strategy: validation

Validate before calling

seen := map[string]bool{}
for orgName, org := range config.Organizations {
    if seen[org.MSPID] {
        return fmt.Errorf("MSP ID %s (org %s) defined more than once", org.MSPID, orgName)
    }
    seen[org.MSPID] = true
}

Type guard

func uniqueMSPIDs(groups map[string]*cb.ConfigGroup) bool {
    ids := map[string]bool{}
    for _, g := range groups {
        id := mspIDFromGroup(g) // extract MSP ID from the group's MSP value
        if ids[id] {
            return false
        }
        ids[id] = true
    }
    return true
}

Try / catch

_, err := ProposeMSP(bh, mspConfig)
if err != nil && strings.Contains(err.Error(), "two different versions of MSP") {
    return fmt.Errorf("MSP ID redefined with different material; use configtxlator to diff configs: %w", err)
}

Prevention

When it happens

Trigger: A single channel config (or config update) contains two MSP definitions with the same MSP ID but different Config bytes — e.g. different root certs, admin certs, or crypto material for the same org MSP name.

Common situations: Redefining an org's MSP (rotating certs) without removing/re-adding the org; duplicate org definitions in configtx.yaml with the same MSP ID but divergent material; copying an org and editing its certs while keeping the same name.

Related errors


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