{"record":{"id":"817dd11f5c79c6df","repo":"hyperledger/fabric","slug":"application-org-s-attempted-to-change-msp-id-from","errorCode":null,"errorMessage":"application org %s attempted to change MSP ID from %s to %s","messagePattern":"application org (.+?) attempted to change MSP ID from (.+?) to (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/channelconfig/bundle.go","lineNumber":132,"sourceCode":"\t\t\t\treturn errors.Errorf(\"orderer org %s attempted to change MSP ID from %s to %s\", orgName, mspID, norg.MSPID())\n\t\t\t}\n\t\t}\n\t}\n\n\tif ac, ok := b.ApplicationConfig(); ok {\n\t\tnac, ok := nb.ApplicationConfig()\n\t\tif !ok {\n\t\t\treturn errors.New(\"current config has application section, but new config does not\")\n\t\t}\n\n\t\tfor orgName, org := range ac.Organizations() {\n\t\t\tnorg, ok := nac.Organizations()[orgName]\n\t\t\tif !ok {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tmspID := org.MSPID()\n\t\t\tif mspID != norg.MSPID() {\n\t\t\t\treturn errors.Errorf(\"application org %s attempted to change MSP ID from %s to %s\", orgName, mspID, norg.MSPID())\n\t\t\t}\n\t\t}\n\t}\n\n\tif cc, ok := b.ConsortiumsConfig(); ok {\n\t\tncc, ok := nb.ConsortiumsConfig()\n\t\tif !ok {\n\t\t\treturn errors.Errorf(\"current config has consortiums section, but new config does not\")\n\t\t}\n\n\t\tfor consortiumName, consortium := range cc.Consortiums() {\n\t\t\tnconsortium, ok := ncc.Consortiums()[consortiumName]\n\t\t\tif !ok {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tfor orgName, org := range consortium.Organizations() {\n\t\t\t\tnorg, ok := nconsortium.Organizations()[orgName]","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/channelconfig/bundle.go#L114-L150","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Keep the application org's MSP ID unchanged in the new config; diff current vs proposed config with configtxlator to confirm.","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.","Correct the typo in the org's 'ID:' field and rebuild the update transaction.","Fetch the live channel config ('peer channel fetch config') and programmatically compare MSP values before submitting the update."],"exampleFix":"// before (configtx.yaml)\n- &Org1\n  Name: Org1\n  ID: Org1NewMSP    # changed from Org1MSP\n// after\n- &Org1\n  Name: Org1\n  ID: Org1MSP       # unchanged\n","handlingStrategy":"validation","validationCode":"// Validate application org MSP IDs are preserved before proposing the update\nfunc checkAppMSPIDs(current, proposed *cb.Config) error {\n\tcurApp := current.Groups[\"Application\"]\n\tnewApp, ok := proposed.Groups[\"Application\"]\n\tif curApp == nil || !ok {\n\t\treturn nil\n\t}\n\tfor name, old := range curApp.Groups {\n\t\tif newG, ok := newApp.Groups[name]; ok && mspIDOf(old) != mspIDOf(newG) {\n\t\t\treturn fmt.Errorf(\"app org %s MSP ID would change\", name)\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func sameMSPID(a, b *cb.ConfigGroup) bool {\n\treturn mspIDOf(a) != \"\" && mspIDOf(a) == mspIDOf(b)\n}","tryCatchPattern":"if err := configtxManager.ProposeConfigUpdate(env); err != nil {\n\tif strings.Contains(err.Error(), \"application org\") && strings.Contains(err.Error(), \"MSP ID\") {\n\t\treturn fmt.Errorf(\"revert the MSP ID change and resubmit: %w\", err)\n\t}\n\treturn err\n}","preventionTips":["Never rename/replace the ID field of an existing application org; add new orgs under new names instead","Diff proposed vs current channel config JSON and inspect every 'MSP' value before signing the update","When migrating CAs or regenerating MSP material, keep the MSP ID string stable","Automate config review: reject any update whose diff touches MSP values for pre-existing orgs"],"tags":["hyperledger-fabric","msp","channel-config","config-update"],"backgroundTag":"immutable-msp-id-violation","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}