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

  1. Pass the identical validation/endorsement policy bytes as the committed definition, or bump the sequence number
  2. Inspect the committed policy via 'peer lifecycle chaincode querycommitted' and reuse that exact policy specification
  3. 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

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


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/3c7b4ed8e539a83b. Report an issue: GitHub.