hyperledger/fabric · error

chaincode '%s' does not require initialization but called as

Error message

chaincode '%s' does not require initialization but called as init

What it means

In Fabric v2.0, chaincodes that require explicit initialization enforce 'init exactly once' semantics via an 'initialized' key in their namespace. This error is returned by CheckInvocation when the client sets input.IsInit=true but the chaincode's definition has EnforceInit=false — i.e. this chaincode does not use the new --init-required flow, so calling it 'as init' is invalid. Legacy (v1.x) chaincodes are the typical case, since old InstantiationPolicy rules govern them and IsInit is rejected.

Source

Thrown at core/chaincode/chaincode_support.go:247

	}

	needsInitialization := false
	if cii.EnforceInit {

		value, err := txParams.TXSimulator.GetState(chaincodeName, InitializedKeyName)
		if err != nil {
			return "", 0, errors.WithMessage(err, "could not get 'initialized' key")
		}

		needsInitialization = !bytes.Equal(value, []byte(cii.Version))
	}

	// Note, IsInit is a new field for v2.0 and should only be set for invocations of non-legacy chaincodes.
	// Any invocation of a legacy chaincode with IsInit set will fail.  This is desirable, as the old
	// InstantiationPolicy contract enforces which users may call init.
	if input.IsInit {
		if !cii.EnforceInit {
			return "", 0, errors.Errorf("chaincode '%s' does not require initialization but called as init", chaincodeName)
		}

		if !needsInitialization {
			return "", 0, errors.Errorf("chaincode '%s' is already initialized but called as init", chaincodeName)
		}

		err = txParams.TXSimulator.SetState(chaincodeName, InitializedKeyName, []byte(cii.Version))
		if err != nil {
			return "", 0, errors.WithMessage(err, "could not set 'initialized' key")
		}

		return cii.ChaincodeID, pb.ChaincodeMessage_INIT, nil
	}

	if needsInitialization {
		return "", 0, errors.Errorf("chaincode '%s' has not been initialized for this version, must call as init first", chaincodeName)
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Remove the isInit flag from the invocation and call the chaincode as a normal transaction.
  2. If init semantics are actually required, redefine the chaincode as v2 format with '--init-required' during approve/commit so EnforceInit becomes true.
  3. For legacy chaincodes, use the old instantiation path instead of the v2 IsInit mechanism.
  4. Update SDK/client code to only set isInit when the committed definition specifies initRequired:true.

Example fix

// before
args := [][]byte{[]byte("Init"), []byte("a"), []byte("100")}
req := channel.Request{ChaincodeID: "mycc", Fcn: "init", Args: args, IsInit: true}
// after (chaincode committed without --init-required)
req := channel.Request{ChaincodeID: "mycc", Fcn: "init", Args: args} // no IsInit
Defensive patterns

Strategy: validation

Validate before calling

// only set isInit when the committed definition requires init
committed, _ := queryCommitted(channelName, chaincodeName) // e.g. via peer CLI/SDK
requireInit := committed != nil && committed.InitRequired
if wantInit && !requireInit {
    return fmt.Errorf("chaincode %s does not require init; drop the isInit flag", chaincodeName)
}

Type guard

func isInitFlagMismatch(err error, chaincodeName string) bool {
    return err != nil && strings.Contains(err.Error(),
        fmt.Sprintf("chaincode '%s' does not require initialization but called as init", chaincodeName))
}

Prevention

When it happens

Trigger: Calling ChaincodeSupport.Invoke (client-side 'peer chaincode invoke -isInit' or SDK equivalents) with IsInit=true against a chaincode whose endorsement info reports EnforceInit==false (deployed without --init-required, or a v1.x legacy chaincode).

Common situations: Client/SDK sending isInit:true by default against a chaincode committed with --init-required omitted; invoking a legacy v1.x chaincode upgraded onto a v2 peer with isInit set; mixing SDK init flags with old instantiation flow.

Related errors


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