hyperledger/fabric · error

expected InitRequired '%t' does not match passed InitRequire

Error message

expected InitRequired '%t' does not match passed InitRequired '%t'

What it means

Thrown by ChaincodeParameters.Equal when the InitRequired boolean in the new definition differs from the committed definition. The lifecycle system treats a change of init requirement as a redefinition that must go through a new sequence number.

Source

Thrown at core/chaincode/lifecycle/lifecycle.go:130

// ChaincodeParameters are the parts of the chaincode definition which are serialized
// as values in the statedb.  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 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

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Set InitRequired to the same value as the committed definition, or bump the sequence number
  2. Check the committed definition with 'peer lifecycle chaincode querycommitted' for the Requires-init flag
  3. Re-approve consistently across all organizations with the intended InitRequired value

Example fix

// before
InitRequired: true, sequence: 1 // committed has InitRequired=false
// after
InitRequired: false, sequence: 1 // or sequence: 2 with InitRequired: true
Defensive patterns

Strategy: validation

Validate before calling

committed, err := lifecycle.QueryChaincodeDefinition(chname, ccname, publicState)
if err == nil && newDef.EndorsementInfo.InitRequired != committed.EndorsementInfo.InitRequired && newDef.Sequence == committed.Sequence {
    return fmt.Errorf("InitRequired change requires sequence bump")
}

Type guard

func sameInitRequired(a, b *lifecycle.ChaincodeParameters) bool {
    return a != nil && b != nil && a.EndorsementInfo.InitRequired == b.EndorsementInfo.InitRequired
}

Try / catch

if err := params.Equal(committedParams); err != nil {
    if strings.Contains(err.Error(), "InitRequired") {
        // re-approve with the committed InitRequired value or sequence+1
    }
    return err
}

Prevention

When it happens

Trigger: Committing a chaincode definition where EndorsementInfo.InitRequired differs from the stored definition; checked during commit-readiness/redefine comparison.

Common situations: Fabric v2.x chaincodes flipping --init-required on/off between approvals; one org approving with InitRequired=true and the operator re-committing with false without bumping the sequence.

Related errors


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