hyperledger/fabric · error

could not get channel config for channel '%s'

Error message

could not get channel config for channel '%s'

What it means

This error is returned by ValidatorCommitter.ImplicitCollectionEndorsementPolicyAsBytes in core/chaincode/lifecycle/deployedcc_infoprovider.go:268 when GetStableChannelConfig(channelID) returns nil. It means the lifecycle layer could not obtain a stable snapshot of the channel's configuration while resolving the implicit collection endorsement policy for an org. It is returned as unexpectedErr (not validationErr), signaling an infrastructure/state problem rather than a bad transaction.

Source

Thrown at core/chaincode/lifecycle/deployedcc_infoprovider.go:268

		requiredPeerCount = vc.PrivdataConfig.ImplicitCollDisseminationPolicy.RequiredPeerCount
		maxPeerCount = vc.PrivdataConfig.ImplicitCollDisseminationPolicy.MaxPeerCount
	}
	return &pb.StaticCollectionConfig{
		Name: implicitcollection.NameForOrg(mspid),
		MemberOrgsPolicy: &pb.CollectionPolicyConfig{
			Payload: &pb.CollectionPolicyConfig_SignaturePolicy{
				SignaturePolicy: policydsl.SignedByMspMember(mspid),
			},
		},
		RequiredPeerCount: int32(requiredPeerCount),
		MaximumPeerCount:  int32(maxPeerCount),
	}
}

func (vc *ValidatorCommitter) ImplicitCollectionEndorsementPolicyAsBytes(channelID, orgMSPID string) (policy []byte, unexpectedErr, validationErr error) {
	channelConfig := vc.Resources.ChannelConfigSource.GetStableChannelConfig(channelID)
	if channelConfig == nil {
		return nil, errors.Errorf("could not get channel config for channel '%s'", channelID), nil
	}

	ac, ok := channelConfig.ApplicationConfig()
	if !ok {
		return nil, errors.Errorf("could not get application config for channel '%s'", channelID), nil
	}

	matchedOrgName := ""
	for orgName, org := range ac.Organizations() {
		if org.MSPID() == orgMSPID {
			matchedOrgName = orgName
			break
		}
	}

	if matchedOrgName == "" {
		return nil, nil, errors.Errorf("no org found in channel with MSPID '%s'", orgMSPID)
	}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Verify the channelID passed to the transaction matches a channel the peer has actually joined (peer channel list).
  2. Re-check that the channel config source is initialized and the channel exists in the ledger before invoking.
  3. Restart/re-sync the peer so channel resources are recreated if the channel was recently modified.
  4. If transient (channel update in flight), retry the transaction after the channel stabilizes.
Defensive patterns

Strategy: validation

Validate before calling

// Go: before invoking, verify the peer knows the channel
channels, _ := peerChannelList()
found := slices.Contains(channels, channelID)
if !found { return fmt.Errorf("channel %s not joined", channelID) }

Type guard

func hasChannelConfig(src ChannelConfigSource, ch string) bool { return src.GetStableChannelConfig(ch) != nil }

Try / catch

if unexpectedErr != nil {
  if strings.Contains(unexpectedErr.Error(), "could not get channel config") {
    // recover: verify channel exists / retry after channel resources ready
  }
}

Prevention

When it happens

Trigger: Called via CollectionValidationInfo when validating a transaction that touches an implicit collection (_implicit_org_<MSPID>) and the channel config channel does not exist in the channel config source (e.g. channel not loaded, wrong channelID, ledger/channel being closed or torn down).

Common situations: Transactions referencing a channel that no longer exists or was renamed; peer joining/leaving a channel concurrently; a channelID typo in SDK invocation; peer has not fetched channel config yet during startup.

Related errors


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