hyperledger/fabric · error

SatisfiesPrincipalInternal shall not be called with a Combin

Error message

SatisfiesPrincipalInternal shall not be called with a CombinedPrincipal

What it means

satisfiesPrincipalInternalV13 in msp/mspimpl.go refuses to evaluate an MSPPrincipal with classification COMBINED. Combined principals must be broken apart and each component evaluated by the appropriate inner MSP, so calling this single-MSP method with one is a programming error by the caller, not a property of the identity.

Source

Thrown at msp/mspimpl.go:590

				return nil
			}
		}

		// if we are here, no match was found, return an error
		return errors.New("The identities do not match")
	default:
		return errors.Errorf("invalid principal type %d", int32(principal.PrincipalClassification))
	}
}

// satisfiesPrincipalInternalV13 takes as arguments the identity and the principal.
// The function returns an error if one occurred.
// The function implements the additional behavior expected of an MSP starting from v1.3.
// For pre-v1.3 functionality, the function calls the satisfiesPrincipalInternalPreV13.
func (msp *bccspmsp) satisfiesPrincipalInternalV13(id Identity, principal *m.MSPPrincipal) error {
	switch principal.PrincipalClassification {
	case m.MSPPrincipal_COMBINED:
		return errors.New("SatisfiesPrincipalInternal shall not be called with a CombinedPrincipal")
	case m.MSPPrincipal_ANONYMITY:
		anon := &m.MSPIdentityAnonymity{}
		err := proto.Unmarshal(principal.Principal, anon)
		if err != nil {
			return errors.Wrap(err, "could not unmarshal MSPIdentityAnonymity from principal")
		}
		switch anon.AnonymityType {
		case m.MSPIdentityAnonymity_ANONYMOUS:
			return errors.New("Principal is anonymous, but X.509 MSP does not support anonymous identities")
		case m.MSPIdentityAnonymity_NOMINAL:
			return nil
		default:
			return errors.Errorf("Unknown principal anonymity type: %d", anon.AnonymityType)
		}

	default:
		// Use the pre-v1.3 function to check other principal types
		return msp.satisfiesPrincipalInternalPreV13(id, principal)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Unwrap the combined principal and evaluate each of its sub-principals against the appropriate MSPs, combining results with the intended AND/OR logic.
  2. Use the top-level policy/ACL evaluation entry point (e.g. policy evaluation via a PrincipalSet/policy provider) instead of calling a single MSP's satisfiesPrincipalInternal with a combined principal.
  3. If you only intended a single-MSP check, change the principal to ROLE/ANONYMITY classification instead of COMBINED.

Example fix

// before
err := identity.SatisfiesPrincipal(combinedPrincipal)
// after
for _, sub := range combinedSubPrincipals {
    if err := identity.SatisfiesPrincipal(sub); err == nil { break }
}
Defensive patterns

Strategy: type-guard

Validate before calling

if principal.PrincipalClassification == m.MSPPrincipal_COMBINED {
	// split into sub-principals and evaluate each against its MSP first
}

Type guard

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

Prevention

When it happens

Trigger: Calling identity.SatisfiesPrincipal on a bccspmsp identity with a principal whose PrincipalClassification is m.MSPPrincipal_COMBINED; a caller that did not pre-split a combined principal into its nested sub-principals.

Common situations: Application code builds a combined (nested OR/AND) principal for endorsement policy but hands it straight to one MSP instead of using the combined-principal evaluation helper; copying policy code from newer fabric versions into a v1.3-era code path.

Related errors


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