{"record":{"id":"473e10df61cbaeb5","repo":"hyperledger/fabric","slug":"unexpected-missing-policy-s-for-item-s","errorCode":null,"errorMessage":"unexpected missing policy %s for item %s","messagePattern":"unexpected missing policy (.+?) for item (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/configtx/update.go","lineNumber":93,"sourceCode":"\t\tif err := validateModPolicy(value.modPolicy()); err != nil {\n\t\t\treturn errors.Wrapf(err, \"invalid mod_policy for element %s\", key)\n\t\t}\n\n\t\texisting, ok := vi.configMap[key]\n\t\tif !ok {\n\t\t\tif value.version() != 0 {\n\t\t\t\treturn errors.Errorf(\"attempted to set key %s to version %d, but key does not exist\", key, value.version())\n\t\t\t}\n\n\t\t\tcontinue\n\t\t}\n\t\tif value.version() != existing.version()+1 {\n\t\t\treturn errors.Errorf(\"attempt to set key %s to version %d, but key is at version %d\", key, value.version(), existing.version())\n\t\t}\n\n\t\tpolicy, ok := vi.policyForItem(existing)\n\t\tif !ok {\n\t\t\treturn errors.Errorf(\"unexpected missing policy %s for item %s\", existing.modPolicy(), key)\n\t\t}\n\n\t\t// Ensure the policy is satisfied\n\t\tif err := policy.EvaluateSignedData(signedData); err != nil {\n\t\t\tlogger.Warnw(\"policy not satisfied for channel configuration update\", \"key\", key, \"policy\", policy, \"signingIdenties\", protoutil.LogMessageForSerializedIdentities(signedData))\n\t\t\treturn errors.Wrapf(err, \"policy for %s not satisfied\", key)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc verifyFullProposedConfig(writeSet, fullProposedConfig map[string]comparable) error {\n\tfor key := range writeSet {\n\t\tif _, ok := fullProposedConfig[key]; !ok {\n\t\t\treturn errors.Errorf(\"writeset contained key %s which did not appear in proposed config\", key)\n\t\t}\n\t}\n\treturn nil","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/configtx/update.go#L75-L111","documentation":"During channel config update verification, verifyDeltaSet could not find the modification policy named by an existing config item's mod_policy. The validator needs this policy to check that the update signatures authorize the change; without it the update is rejected as malformed or corrupt. This usually means the existing config references a policy that does not exist in the current channel config.","triggerScenarios":"Calling proposeConfigUpdate or Validate with a ConfigUpdateEnvelope whose writeSet modifies an item whose existing entry's mod_policy does not resolve to a policy in the channel's policy manager (e.g. policyForItem returns !ok).","commonSituations":"Hand-edited or tool-generated channel config referencing a mod_policy like 'Admins' under a path where the policy group was removed; upgrading from an older genesis block; a config item whose mod_policy was renamed or deleted in a prior update.","solutions":["Inspect the current channel config (configtxlator proto_decode) and ensure every item's mod_policy resolves to a policy defined at that item's group level.","Regenerate the config update from a valid base config instead of hand-editing, so mod_policy values match existing policies.","Fix the existing channel config via a correct update that redefines or renames the missing policy before modifying the affected item.","Check for channel/group path mistakes: a policy named 'Admins' exists at some groups but not the group owning the item."],"exampleFix":"// before: update item with mod_policy \"Orderers/Admins\" but that policy was removed\n// after: set item.mod_policy to an existing policy, e.g. \"/Channel/Orderer/Admins\",\n// or add the policy back to the config group before submitting the update","handlingStrategy":"validation","validationCode":"// Validate every existing item's mod_policy resolves before proposing an update\nfunc checkModPolicies(cfg *cb.Config, pm policies.PolicyManager) error {\n    return traverseConfigGroups(cfg.ChannelGroup, func(path string, g *cb.ConfigGroup) error {\n        for _, v := range g.Values {\n            if _, ok := pm.GetPolicy(v.ModPolicy); !ok {\n                return fmt.Errorf(\"item %s references missing mod_policy %s\", path, v.ModPolicy)\n            }\n        }\n        return nil\n    })\n}","typeGuard":null,"tryCatchPattern":"// wrap proposeConfigUpdate and detect the missing-policy family\nif _, err := validator.ProposeConfigUpdate(env, seq); err != nil {\n    if strings.Contains(err.Error(), \"unexpected missing policy\") {\n        // fix config mod_policy references, rebuild update\n    }\n    return err\n}","preventionTips":["Never hand-edit serialized channel config; always derive updates from configtxlator diffs of the live config.","After any update that removes or renames a policy, audit remaining items' mod_policy references.","Keep mod_policy names consistent with the standard group policies (Admins, Readers, Writers, Orderer)."],"tags":["hyperledger-fabric","configtx","policy","channel-config"],"backgroundTag":"missing-mod-policy","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"}