{"record":{"id":"58f39a8ffb2f107e","repo":"hyperledger/fabric","slug":"mod-policy-not-set","errorCode":null,"errorMessage":"mod_policy not set","messagePattern":"mod_policy not set","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/configtx/update.go","lineNumber":51,"sourceCode":"func computeDeltaSet(readSet, writeSet map[string]comparable) map[string]comparable {\n\tresult := make(map[string]comparable)\n\tfor key, value := range writeSet {\n\t\treadVal, ok := readSet[key]\n\n\t\tif ok && readVal.version() == value.version() {\n\t\t\tcontinue\n\t\t}\n\n\t\t// If the key in the readset is a different version, we include it\n\t\t// Error checking on the sanity of the update is done against the config\n\t\tresult[key] = value\n\t}\n\treturn result\n}\n\nfunc validateModPolicy(modPolicy string) error {\n\tif modPolicy == \"\" {\n\t\treturn errors.Errorf(\"mod_policy not set\")\n\t}\n\n\ttrimmed := modPolicy\n\tif modPolicy[0] == '/' {\n\t\ttrimmed = modPolicy[1:]\n\t}\n\n\tfor i, pathElement := range strings.Split(trimmed, pathSeparator) {\n\t\terr := validateConfigID(pathElement)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"path element at %d is invalid\", i)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (vi *ValidatorImpl) verifyDeltaSet(deltaSet map[string]comparable, signedData []*protoutil.SignedData) error {\n\tif len(deltaSet) == 0 {","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/configtx/update.go#L33-L69","documentation":"validateModPolicy rejects any config element whose mod_policy field is empty. mod_policy names the policy that governs modification of that element, and a config element without one cannot be validated or updated.","triggerScenarios":"A delta-set entry (or a nested config element validated via the anonymous caller) has an empty mod_policy string.","commonSituations":"Constructing ConfigValue/ConfigGroup/ConfigPolicy programmatically and forgetting to set ModPolicy; config produced by older tooling that omitted mod_policy.","solutions":["Set ModPolicy on the config element, e.g. 'Admins' or '/Channel/Application/Admins'.","Regenerate the config with configtxgen or a current SDK that populates mod_policy.","Check the tool/script that assembles the ConfigUpdate for missing ModPolicy assignments."],"exampleFix":"// before\n&cb.ConfigValue{Value: bytes, Version: 1}\n// after\n&cb.ConfigValue{Value: bytes, Version: 1, ModPolicy: \"Admins\"}","handlingStrategy":"validation","validationCode":"func requireModPolicy(el interface{ GetModPolicy() string }) error {\n  if el.GetModPolicy() == \"\" { return errors.New(\"element missing ModPolicy\") }\n  return nil\n}","typeGuard":"func hasModPolicy(el *cb.ConfigValue) bool { return el != nil && el.GetModPolicy() != \"\" }","tryCatchPattern":"err := validator.ProposeUpdate(env)\nif err != nil && strings.Contains(err.Error(), \"mod_policy not set\") {\n  return fmt.Errorf(\"update rejected: set ModPolicy on all changed elements: %w\", err)\n}","preventionTips":["Set ModPolicy on every ConfigValue/ConfigGroup/ConfigPolicy you construct","Use configtxgen or a maintained SDK that populates mod_policy","Lint generated configs for empty ModPolicy fields before submission"],"tags":["hyperledger-fabric","configtx","mod-policy"],"backgroundTag":"mod-policy-not-set","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"}