hyperledger/fabric · error
full config did not verify
Error message
full config did not verify
What it means
After policy verification, the fully computed proposed config failed verifyFullProposedConfig — some writeSet key is missing from the resulting full config. This wraps error 152 and indicates the update, though policy-authorized, produces an inconsistent result: the written key cannot be located in the recomputed config tree.
Source
Thrown at common/configtx/update.go:156
writeSet, err := mapConfig(configUpdate.WriteSet, vi.namespace)
if err != nil {
return nil, errors.Wrapf(err, "error mapping WriteSet")
}
deltaSet := computeDeltaSet(readSet, writeSet)
signedData, err := protoutil.ConfigUpdateEnvelopeAsSignedData(configUpdateEnv)
if err != nil {
return nil, err
}
if err = vi.verifyDeltaSet(deltaSet, signedData); err != nil {
return nil, errors.Wrapf(err, "error validating DeltaSet")
}
fullProposedConfig := vi.computeUpdateResult(deltaSet)
if err := verifyFullProposedConfig(writeSet, fullProposedConfig); err != nil {
return nil, errors.Wrapf(err, "full config did not verify")
}
return fullProposedConfig, nil
}
func (vi *ValidatorImpl) policyForItem(item comparable) (policies.Policy, bool) {
manager := vi.pm
modPolicy := item.modPolicy()
logger.Debugf("Getting policy for item %s with mod_policy %s", item.key, modPolicy)
// If the mod_policy path is relative, get the right manager for the context
// If the item has a zero length path, it is the root group, use the base policy manager
// if the mod_policy path is absolute (starts with /) also use the base policy manager
if len(modPolicy) > 0 && modPolicy[0] != policies.PathSeparator[0] && len(item.path) != 0 {
var ok bool
manager, ok = manager.Manager(item.path[1:])View on GitHub (pinned to 2736b63f8f)
Solutions
- Regenerate the update via configtxlator diff from the current config to guarantee writeSet keys map into the full config.
- Compare writeSet key paths against the config tree and fix paths that don't correspond to any group/value/policy position.
- Confirm the update was derived from the target channel's current config.
- Remove writeSet keys that are not legitimate intended changes.
Example fix
// before: writeSet key "Channel/Group/Value" (flat path) not reproducible // after: place it correctly: groups.Channel.groups.Group.values.Value update.WriteSet.Groups["Application"].Values["BatchSize"] = ...
Defensive patterns
Strategy: validation
Validate before calling
// Simulate: every writeSet key must exist in the recomputed config result
func keysInResult(writeSet *cb.ConfigGroup, result map[string]interface{}) error {
// iterate writeSet keys and assert presence in computeUpdateResult output
return verifyWriteKeysPresent(writeSet, result)
} Try / catch
if _, err := validator.ProposeConfigUpdate(env, seq); err != nil {
if strings.Contains(err.Error(), "full config did not verify") {
// rebuild the update as a proper diff of the live config
}
return err
} Prevention
- Derive updates exclusively from configtxlator diffs of the fetched live config.
- Never reuse update files across channels or across config versions.
- After building an update, decode it back to JSON and eyeball the key paths against the config tree.
When it happens
Trigger: Calling proposeConfigUpdate/Validate where the delta applied by computeUpdateResult yields a full config lacking a writeSet key — malformed writeSet paths or keys not derivable from the config structure.
Common situations: Programmatically constructed updates with paths that don't mirror the config hierarchy; updates built from a different channel's config; manual proto edits that break key naming.
Related errors
- writeset contained key %s which did not appear in proposed c
- error mapping WriteSet
- Attempted to set the batch size max message count to an inva
- Attempted to set the batch size absolute max bytes to an inv
- Attempted to set the batch size preferred max bytes to an in
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/afd763a0e7694e1b.
Report an issue: GitHub.