hyperledger/fabric · error
expected ValidationParameter '%x' does not match passed Vali
Error message
expected ValidationParameter '%x' does not match passed ValidationParameter '%x'
What it means
Thrown by ChaincodeParameters.Equal when the ValidationParameter bytes (the endorsement policy / validation parameter) of the new definition differ from the committed definition, compared with bytes.Equal.
Source
Thrown at core/chaincode/lifecycle/lifecycle.go:134
// will cause opaque checks to fail.
type ChaincodeParameters struct {
EndorsementInfo *lb.ChaincodeEndorsementInfo
ValidationInfo *lb.ChaincodeValidationInfo
Collections *pb.CollectionConfigPackage
}
func (cp *ChaincodeParameters) Equal(ocp *ChaincodeParameters) error {
switch {
case cp.EndorsementInfo.Version != ocp.EndorsementInfo.Version:
return errors.Errorf("expected Version '%s' does not match passed Version '%s'", cp.EndorsementInfo.Version, ocp.EndorsementInfo.Version)
case cp.EndorsementInfo.EndorsementPlugin != ocp.EndorsementInfo.EndorsementPlugin:
return errors.Errorf("expected EndorsementPlugin '%s' does not match passed EndorsementPlugin '%s'", cp.EndorsementInfo.EndorsementPlugin, ocp.EndorsementInfo.EndorsementPlugin)
case cp.EndorsementInfo.InitRequired != ocp.EndorsementInfo.InitRequired:
return errors.Errorf("expected InitRequired '%t' does not match passed InitRequired '%t'", cp.EndorsementInfo.InitRequired, ocp.EndorsementInfo.InitRequired)
case cp.ValidationInfo.ValidationPlugin != ocp.ValidationInfo.ValidationPlugin:
return errors.Errorf("expected ValidationPlugin '%s' does not match passed ValidationPlugin '%s'", cp.ValidationInfo.ValidationPlugin, ocp.ValidationInfo.ValidationPlugin)
case !bytes.Equal(cp.ValidationInfo.ValidationParameter, ocp.ValidationInfo.ValidationParameter):
return errors.Errorf("expected ValidationParameter '%x' does not match passed ValidationParameter '%x'", cp.ValidationInfo.ValidationParameter, ocp.ValidationInfo.ValidationParameter)
case !proto.Equal(cp.Collections, ocp.Collections):
return errors.Errorf("Collections do not match")
default:
}
return nil
}
// ChaincodeDefinition contains the chaincode parameters, as well as the sequence number of the definition.
// Note, it does not embed ChaincodeParameters so as not to complicate the serialization. It is expected
// that any instance will have no nil fields once initialized.
// WARNING: This structure is serialized/deserialized from the DB, re-ordering or adding fields
// will cause opaque checks to fail.
type ChaincodeDefinition struct {
Sequence int64
EndorsementInfo *lb.ChaincodeEndorsementInfo
ValidationInfo *lb.ChaincodeValidationInfo
Collections *pb.CollectionConfigPackage
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Pass the identical validation/endorsement policy bytes as the committed definition, or bump the sequence number
- Inspect the committed policy via 'peer lifecycle chaincode querycommitted' and reuse that exact policy specification
- Re-approve on all orgs with the same endorsement policy before committing
Example fix
// before
--signature-policy "AND('Org1.peer','Org2.peer')", sequence: 1 // committed policy was OR(...)
// after
--signature-policy "OR('Org1.peer','Org2.peer')", sequence: 1 // match, or use sequence: 2 to change Defensive patterns
Strategy: validation
Validate before calling
committed, err := lifecycle.QueryChaincodeDefinition(chname, ccname, publicState)
if err == nil && !bytes.Equal(newDef.ValidationInfo.ValidationParameter, committed.ValidationInfo.ValidationParameter) && newDef.Sequence == committed.Sequence {
return fmt.Errorf("validation parameter change requires sequence bump")
} Type guard
func sameValidationParameter(a, b *lifecycle.ChaincodeParameters) bool {
return a != nil && b != nil && bytes.Equal(a.ValidationInfo.ValidationParameter, b.ValidationInfo.ValidationParameter)
} Try / catch
if err := params.Equal(committedParams); err != nil {
if strings.Contains(err.Error(), "ValidationParameter") {
// reuse the committed policy bytes or bump sequence
}
return err
} Prevention
- Store the endorsement policy specification in version control and reuse it verbatim
- Avoid reformatting policy JSON between approvals — bytes must match
- Re-approve all orgs whenever the policy changes, with sequence+1
When it happens
Trigger: Committing a definition whose --endorsement-policy or --signature-policy bytes differ from the committed one at the same sequence; redefine comparison in lifecycle.
Common situations: Changing the endorsement policy between approvals without bumping sequence; policy expressed with different (but non-identical) JSON that serializes to different bytes; org approvals disagreeing on policy.
Related errors
- chaincode definition for [%s] is invalid, policy field must
- failed listing installed chaincodes
- failed to parse collection config
- [channel %s] failed to get chaincode container info for %s
- chaincode '%s' does not require initialization but called as
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/3c7b4ed8e539a83b.
Report an issue: GitHub.