hyperledger/fabric · error

invalid principal type %d

Error message

invalid principal type %d

What it means

collectPrincipals rejects MSPPrincipal values classified as COMBINED when the MSP version is v1.0 or v1.1, with 'invalid principal type %d' reporting the numeric classification. Combined principals (MSPv1_3+) allow nesting multiple principals into an AND-group, and older MSP versions explicitly do not understand them.

Source

Thrown at msp/mspimpl.go:454

	if err != nil {
		return err
	}
	for _, principal := range principals {
		err = msp.internalSatisfiesPrincipalInternalFunc(id, principal)
		if err != nil {
			return err
		}
	}
	return nil
}

// collectPrincipals collects principals from combined principals into a single MSPPrincipal slice.
func collectPrincipals(principal *m.MSPPrincipal, mspVersion MSPVersion) ([]*m.MSPPrincipal, error) {
	switch principal.PrincipalClassification {
	case m.MSPPrincipal_COMBINED:
		// Combined principals are not supported in MSP v1.0 or v1.1
		if mspVersion <= MSPv1_1 {
			return nil, errors.Errorf("invalid principal type %d", int32(principal.PrincipalClassification))
		}
		// Principal is a combination of multiple principals.
		principals := &m.CombinedPrincipal{}
		err := proto.Unmarshal(principal.Principal, principals)
		if err != nil {
			return nil, errors.Wrap(err, "could not unmarshal CombinedPrincipal from principal")
		}
		// Return an error if there are no principals in the combined principal.
		if len(principals.Principals) == 0 {
			return nil, errors.New("No principals in CombinedPrincipal")
		}
		// Recursively call msp.collectPrincipals for all combined principals.
		// There is no limit for the levels of nesting for the combined principals.
		var principalsSlice []*m.MSPPrincipal
		for _, cp := range principals.Principals {
			internalSlice, err := collectPrincipals(cp, mspVersion)
			if err != nil {
				return nil, err

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Enable the V1_3 (or later) channel capability and update the MSP version so combined principals are accepted
  2. Rewrite the policy to avoid MSPPrincipal_COMBINED: use implicit meta policies or express the logic as a signature policy tree instead
  3. If rejection is intended, nothing to fix — the error is the guard against using v1.3 features on an older MSP

Example fix

// before (channel config)
Capabilities:
  Channel: {V1_1: true}   # combined principals rejected
// after
Capabilities:
  Channel: {V1_3: true}   # MSPv1_3, combined principals supported
Defensive patterns

Strategy: validation

Validate before calling

func combinedPrincipalsSupported(version msp.MSPVersion) bool {
    return version > msp.MSPv1_1 // e.g. MSPv1_3
}
// before evaluating a policy, check principal.PrincipalClassification != m.MSPPrincipal_COMBINED || combinedPrincipalsSupported(mspVersion)

Type guard

func isCombinedPrincipal(p *m.MSPPrincipal) bool {
    return p != nil && p.PrincipalClassification == m.MSPPrincipal_COMBINED
}

Try / catch

principals, err := msp.SatisfiesPrincipal(id, principal)
if err != nil {
    if strings.Contains(err.Error(), "invalid principal type") {
        // COMBINED principal on an MSP <= v1.1; upgrade MSP version or rewrite policy
    }
    return err
}

Prevention

When it happens

Trigger: Calling SatisfiesPrincipal (or any policy evaluation path that calls collectPrincipals) against an MSPPrincipal with PrincipalClassification=MSPPrincipal_COMBINED while the MSP's version is MSPv1_0 or MSPv1_1. Also produced directly by unit tests TestCollectEmptyCombinedPrincipal and TestCollectPrincipalContainingEmptyCombinedPrincipal which assert this rejection.

Common situations: Channel/application config still at MSP v1.1 (set via configtx Channel capabilities / MSPVersion) while an endorsement or ACL policy was authored with a combined principal; upgrading policies without upgrading channel capabilities to V1_3 or later.

Related errors


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