hyperledger/fabric · error

policy '%s' must be defined for channel '%s' before chaincod

Error message

policy '%s' must be defined for channel '%s' before chaincode operations can be attempted

What it means

The channel exists, but its config does not define a policy named by DefaultEndorsementPolicyRef (default endorsement policy /channel/config style ref). Lifecycle refuses to fabricate a policy and requires the channel to explicitly define it before chaincode operations proceed.

Source

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

	}

	return approvals, nil
}

// DefaultEndorsementPolicyAsBytes returns a marshalled version
// of the default chaincode endorsement policy in the supplied channel
func (ef *ExternalFunctions) DefaultEndorsementPolicyAsBytes(channelID string) ([]byte, error) {
	channelConfig := ef.Resources.ChannelConfigSource.GetStableChannelConfig(channelID)
	if channelConfig == nil {
		return nil, errors.Errorf("could not get channel config for channel '%s'", channelID)
	}

	// see if the channel defines a default
	if _, ok := channelConfig.PolicyManager().GetPolicy(DefaultEndorsementPolicyRef); ok {
		return DefaultEndorsementPolicyBytes, nil
	}

	return nil, errors.Errorf(
		"policy '%s' must be defined for channel '%s' before chaincode operations can be attempted",
		DefaultEndorsementPolicyRef,
		channelID,
	)
}

// SetChaincodeDefinitionDefaults fills any empty fields in the
// supplied ChaincodeDefinition with the supplied channel's defaults
func (ef *ExternalFunctions) SetChaincodeDefinitionDefaults(chname string, cd *ChaincodeDefinition) error {
	if cd.EndorsementInfo.EndorsementPlugin == "" {
		// TODO:
		// 1) rename to "default" or "builtin"
		// 2) retrieve from channel config
		cd.EndorsementInfo.EndorsementPlugin = "escc"
	}

	if cd.ValidationInfo.ValidationPlugin == "" {
		// TODO:

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Define the required default policy in the channel config (update the channel config to include the application-level endorsement policy)
  2. Supply an explicit endorsement policy in the chaincode definition so the default is not needed
  3. Regenerate the channel genesis from a current configtx profile that includes the default policy

Example fix

// before (relying on missing channel default)
definition := &lifecycle.ChaincodeDefinition{Sequence: 1}
// after (explicit policy)
definition := &lifecycle.ChaincodeDefinition{Sequence: 1, EndorsementPolicy: policyBytesFromApplicationPolicy("MAJORITY Endorsement")}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check that the channel defines the default endorsement policy
cc := ccSource.GetStableChannelConfig(ch)
if cc == nil { return fmt.Errorf("no channel config for %q", ch) }
if _, ok := cc.PolicyManager().GetPolicy(lifecycle.DefaultEndorsementPolicyRef); !ok {
    return fmt.Errorf("channel %q must define policy %s", ch, lifecycle.DefaultEndorsementPolicyRef)
}

Try / catch

bytes, err := ef.DefaultEndorsementPolicyAsBytes(ch)
if err != nil {
    if strings.Contains(err.Error(), "must be defined for channel") {
        // fall back to supplying an explicit endorsement policy
    }
    return err
}

Prevention

When it happens

Trigger: Approving or committing a chaincode definition on a channel whose config lacks the '/Channel/Application/<DefaultEndorsementPolicyRef>' policy while no explicit endorsement policy is supplied in the definition.

Common situations: Channels created from old genesis templates that predate the default endorsement policy; custom channel profiles missing the application policy; operators assuming an implicit default policy exists.

Related errors


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