hyperledger/fabric · error
attempted to set key %s to version %d, but key does not exis
Error message
attempted to set key %s to version %d, but key does not exist
What it means
For a new element (absent from the current config map), the proposed version must be 0. This error means the update tries to add a key that doesn't currently exist but assigns it a non-zero version, which is inconsistent with how the versioning works.
Source
Thrown at common/configtx/update.go:82
}
return nil
}
func (vi *ValidatorImpl) verifyDeltaSet(deltaSet map[string]comparable, signedData []*protoutil.SignedData) error {
if len(deltaSet) == 0 {
return errors.Errorf("delta set was empty -- update would have no effect")
}
for key, value := range deltaSet {
logger.Debugf("Processing change to key: %s", key)
if err := validateModPolicy(value.modPolicy()); err != nil {
return errors.Wrapf(err, "invalid mod_policy for element %s", key)
}
existing, ok := vi.configMap[key]
if !ok {
if value.version() != 0 {
return errors.Errorf("attempted to set key %s to version %d, but key does not exist", key, value.version())
}
continue
}
if value.version() != existing.version()+1 {
return errors.Errorf("attempt to set key %s to version %d, but key is at version %d", key, value.version(), existing.version())
}
policy, ok := vi.policyForItem(existing)
if !ok {
return errors.Errorf("unexpected missing policy %s for item %s", existing.modPolicy(), key)
}
// Ensure the policy is satisfied
if err := policy.EvaluateSignedData(signedData); err != nil {
logger.Warnw("policy not satisfied for channel configuration update", "key", key, "policy", policy, "signingIdenties", protoutil.LogMessageForSerializedIdentities(signedData))
return errors.Wrapf(err, "policy for %s not satisfied", key)
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Set the new element's Version to 0 when adding a key that does not exist in current config.
- Rebuild the write set from the current config rather than cached comparisons.
- If the element should exist, first check whether a concurrent update deleted it and reconcile.
Example fix
// before
delta["/Channel/Application/Org4"] = comparable{ConfigGroup: &cb.ConfigGroup{Version: 2}} // key absent
// after
delta["/Channel/Application/Org4"] = comparable{ConfigGroup: &cb.ConfigGroup{Version: 0}} Defensive patterns
Strategy: validation
Validate before calling
if _, ok := currentConfigMap[key]; !ok && value.version() != 0 {
return fmt.Errorf("new key %s must have version 0", key)
} Type guard
func newElementVersionOK(key string, value comparable, current map[string]comparable) bool {
_, exists := current[key]
return exists || value.version() == 0
} Try / catch
err := validator.ProposeUpdate(env)
if err != nil && strings.Contains(err.Error(), "but key does not exist") {
resetVersionsToZeroForNewKeys(deltaSet, currentConfigMap)
env = rebuildEnvelope(deltaSet) // rebuild and retry once
} Prevention
- Reset Version to 0 whenever adding an element absent from current config
- Never reuse comparable values cached from older configs
- Recompute write sets from the latest config on every submission
When it happens
Trigger: A delta-set entry for a key not in configMap with version() != 0 — e.g. reusing a cached comparable from an old config where the element previously existed but has since been deleted.
Common situations: Re-adding a removed org/group while carrying the old version number; copying a delta set from a different channel config.
Related errors
- proposed update requires that key %s be at version %d, but i
- attempt to set key %s to version %d, but key is at version %
- error validating ReadSet
- Attempted to set the batch size max message count to an inva
- Attempted to set the batch size absolute max bytes to an inv
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/2c8ec214a74f699f.
Report an issue: GitHub.