hyperledger/fabric · error

no instantiation policy was specified

Error message

no instantiation policy was specified

What it means

The ChaincodeData produced by lscc deploy must include an instantiation policy. If the InstantiationPolicy field is nil, the validator cannot verify who is authorized to deploy/upgrade this chaincode, so the transaction is rejected as a policy error.

Source

Thrown at core/handlers/validation/builtin/v12/validation_logic.go:663

			if ac.PrivateChannelData() {
				// do extra validation for collections
				err := vscc.validateRWSetAndCollection(lsccrwset, cdRWSet, lsccArgs, lsccFunc, ac, chid)
				if err != nil {
					return err
				}
			} else {
				// there can only be a single ledger write
				if len(lsccrwset.Writes) != 1 {
					return policyErr(fmt.Errorf("LSCC can only issue a single putState upon deploy"))
				}
			}

			/*****************************************************/
			/* security check 3 - check the instantiation policy */
			/*****************************************************/
			pol := cdRWSet.InstantiationPolicy
			if pol == nil {
				return policyErr(fmt.Errorf("no instantiation policy was specified"))
			}
			// FIXME: could we actually pull the cds package from the
			// file system to verify whether the policy that is specified
			// here is the same as the one on disk?
			// PROS: we prevent attacks where the policy is replaced
			// CONS: this would be a point of non-determinism
			err := vscc.checkInstantiationPolicy(chid, env, pol, payl)
			if err != nil {
				return err
			}

		case lscc.UPGRADE:
			/**************************************************************/
			/* security check 1 - cc in the LCCC table of instantiated cc */
			/**************************************************************/
			if !ccExistsOnLedger {
				return policyErr(fmt.Errorf("Upgrading non-existent chaincode %s", cdsArgs.ChaincodeSpec.ChaincodeId.Name))
			}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Deploy through the standard SDK/lscc path so an instantiation policy is automatically attached from the endorsing peers' signature policy.
  2. Use stock lscc — do not modify ChaincodeData generation.
  3. Rebuild the deployment proposal with a current SDK that includes the instantiation policy in the spec.
  4. Inspect the lscc write value to confirm InstantiationPolicy is present before resubmitting.
Defensive patterns

Strategy: validation

Validate before calling

cd := &ccprovider.ChaincodeData{}
if err := proto.Unmarshal(ns.KvRwSet.Writes[0].Value, cd); err != nil {
    return err
}
if cd.InstantiationPolicy == nil {
    return fmt.Errorf("ChaincodeData lacks instantiation policy; deploy via standard lscc path")
}

Type guard

func hasInstantiationPolicy(cd *ccprovider.ChaincodeData) bool {
    return cd != nil && cd.InstantiationPolicy != nil
}

Try / catch

if err := submitTx(envelope); err != nil {
    if strings.Contains(err.Error(), "no instantiation policy was specified") {
        // rebuild and re-endorse the deploy proposal with a current SDK
    }
}

Prevention

When it happens

Trigger: cdRWSet.InstantiationPolicy is nil after unmarshalling the lscc write — i.e. the ChaincodeData written by lscc lacks an instantiation policy, typically because it was not generated by the stock lscc deploy path.

Common situations: Hand-crafted or modified ChaincodeData / rwsets; running a forked lscc that omits the policy; ledger data written by an older/nonstandard tooling then validated by v12 validator.

Related errors


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