{"record":{"id":"d6d7e241c137b931","repo":"hyperledger/fabric","slug":"attempt-to-set-key-s-to-version-d-but-key-is-at","errorCode":null,"errorMessage":"attempt to set key %s to version %d, but key is at version %d","messagePattern":"attempt to set key (.+?) to version (.+?), but key is at version (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/configtx/update.go","lineNumber":88,"sourceCode":"\t\treturn errors.Errorf(\"delta set was empty -- update would have no effect\")\n\t}\n\n\tfor key, value := range deltaSet {\n\t\tlogger.Debugf(\"Processing change to key: %s\", key)\n\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 {","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/common/configtx/update.go#L70-L106","documentation":"For an existing element, the proposed version must be exactly current+1 (monotonic increment). This error means the update modifies an existing key but supplies the wrong next version — usually a stale version or a skip-ahead version.","triggerScenarios":"A delta-set entry whose version() does not equal existing.version()+1, e.g. version 3 when config is at 5, or version 7 when config is at 5.","commonSituations":"Racing channel updates (another admin bumped the version); a client reusing a write set computed from an older config; manually hard-coded version numbers.","solutions":["Fetch the latest config, then set Version to currentVersion + 1 for each modified element.","Rebuild the entire update against a freshly read config block to clear stale versions.","If the error persists, check for concurrent update submissions and serialize admin operations."],"exampleFix":"// before\nvalue.Version = 3 // config element is at version 5\n// after\nvalue.Version = existingVersion + 1 // 6","handlingStrategy":"retry","validationCode":"if existing, ok := currentConfigMap[key]; ok && value.version() != existing.version()+1 {\n  return fmt.Errorf(\"key %s: expected version %d, got %d\", key, existing.version()+1, value.version())\n}","typeGuard":"func nextVersionOK(value comparable, existing comparable) bool { return value.version() == existing.version()+1 }","tryCatchPattern":"err := validator.ProposeUpdate(env)\nif err != nil && strings.Contains(err.Error(), \"but key is at version\") {\n  env = rebuildUpdateFromLatestConfig() // bump versions and resubmit\n}","preventionTips":["Always set Version to currentVersion+1 for modified elements","Refetch the config block whenever an update fails with a version mismatch","Coordinate admins so updates are submitted serially"],"tags":["hyperledger-fabric","configtx","version-conflict"],"backgroundTag":"config-version-conflict","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"}