hyperledger/fabric · error

could not get application config for channel '%s'

Error message

could not get application config for channel '%s'

What it means

Thrown by Resources.LifecycleEndorsementPolicyAsBytes when the channel config exists but does not implement ApplicationConfig (ok == false). This happens for channels without an application group, so the default majority-of-orgs lifecycle endorsement policy cannot be computed.

Source

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

	return true, definedChaincode, nil
}

func (r *Resources) LifecycleEndorsementPolicyAsBytes(channelID string) ([]byte, error) {
	channelConfig := r.ChannelConfigSource.GetStableChannelConfig(channelID)
	if channelConfig == nil {
		return nil, errors.Errorf("could not get channel config for channel '%s'", channelID)
	}

	if _, ok := channelConfig.PolicyManager().GetPolicy(LifecycleEndorsementPolicyRef); ok {
		return LifecycleDefaultEndorsementPolicyBytes, nil
	}

	// This was a channel which was upgraded or did not define a lifecycle endorsement policy, use a default
	// of "a majority of orgs must have a member sign".
	ac, ok := channelConfig.ApplicationConfig()
	if !ok {
		return nil, errors.Errorf("could not get application config for channel '%s'", channelID)
	}
	orgs := ac.Organizations()
	mspids := make([]string, 0, len(orgs))
	for _, org := range orgs {
		mspids = append(mspids, org.MSPID())
	}

	return protoutil.MarshalOrPanic(&cb.ApplicationPolicy{
		Type: &cb.ApplicationPolicy_SignaturePolicy{
			SignaturePolicy: policydsl.SignedByNOutOfGivenRole(int32(len(mspids)/2+1), msp.MSPRole_MEMBER, mspids),
		},
	}), nil
}

// ExternalFunctions is intended primarily to support the SCC functions.
// In general, its methods signatures produce writes (which must be committed
// as part of an endorsement flow), or return human readable errors (for
// instance indicating a chaincode is not found) rather than sentinels.

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Recreate/reconfigure the channel so it includes an Application group with member organizations
  2. Use a proper application channel for chaincode operations instead of an orderer-only channel
  3. Check the channel's config block (configtxlator) to confirm the Application section and organizations exist

Example fix

// before
Channel profile without Application section in configtx.yaml
// after
Profile:
  Application:
    Organizations:
      - *Org1
      - *Org2
Defensive patterns

Strategy: try-catch

Validate before calling

cfg := channelConfigSource.GetStableChannelConfig(channelID)
if cfg != nil {
    if _, ok := cfg.ApplicationConfig(); !ok {
        return fmt.Errorf("channel %s has no application config; cannot compute lifecycle policy", channelID)
    }
}

Type guard

func hasApplicationConfig(cfg ChannelConfig) bool {
    _, ok := cfg.ApplicationConfig()
    return ok
}

Try / catch

policyBytes, err := resources.LifecycleEndorsementPolicyAsBytes(chid)
if err != nil {
    if strings.Contains(err.Error(), "could not get application config") {
        // recreate channel with an Application group in configtx
    }
    return err
}

Prevention

When it happens

Trigger: Reading the lifecycle endorsement policy for a channel whose stable config has no Application config — typically orderer-only channels or channels created without an application section.

Common situations: System channel or non-application channels on a peer; malformed channel creation where the Application group was omitted; testing against a channel template lacking application orgs.

Related errors


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