hyperledger/fabric · error
invalid identity type, expected *identity
Error message
invalid identity type, expected *identity
What it means
satisfiesPrincipalInternalV142 implements v2.0+ principal-satisfaction behavior for a bccspmsp. Before evaluating the principal it asserts that the passed Identity is the concrete internal type *identity; if the caller supplied any other implementation of the Identity interface (e.g. a mock, a wrapped identity, or a foreign MSP's implementation), the type assertion fails and this error is returned. It is an internal-invariant error, not something a correct caller should ever produce.
Source
Thrown at msp/mspimpl.go:619
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)
}
}
// satisfiesPrincipalInternalV142 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 v2.0.
// For v1.3 functionality, the function calls the satisfiesPrincipalInternalPreV13.
func (msp *bccspmsp) satisfiesPrincipalInternalV142(id Identity, principal *m.MSPPrincipal) error {
_, okay := id.(*identity)
if !okay {
return errors.New("invalid identity type, expected *identity")
}
switch principal.PrincipalClassification {
case m.MSPPrincipal_ROLE:
if !msp.ouEnforcement {
break
}
// Principal contains the msp role
mspRole := &m.MSPRole{}
err := proto.Unmarshal(principal.Principal, mspRole)
if err != nil {
return errors.Wrap(err, "could not unmarshal MSPRole from principal")
}
// at first, we check whether the MSP
// identifier is the same as that of the identity
if mspRole.MspIdentifier != msp.name {View on GitHub (pinned to 2736b63f8f)
Solutions
- Obtain the identity from the same MSP (msp.DeserializeIdentity, msp.GetIdentityFromConf, etc.) so it is the concrete *identity type
- In tests, replace mock Identity types with real identities built via msp.New with valid provider and cert PEM bytes
- Verify the identity was not wrapped or re-created by another layer before being passed to SatisfiesPrincipal
- If you need cross-MSP evaluation, call SatisfiesPrincipal on the MSP that owns the identity
Example fix
// before
var id fabric.Identity = myMockIdentity()
err := msp.SatisfiesPrincipal(id, principal)
// after
id, err := msp.DeserializeIdentity(certPEM)
if err != nil { return err }
err = msp.SatisfiesPrincipal(id, principal) Defensive patterns
Strategy: type-guard
Validate before calling
// ensure the identity comes from this MSP before evaluation
id, err := msp.DeserializeIdentity(certPEM)
if err != nil { return fmt.Errorf("cannot load identity for this MSP: %w", err) }
_ = id // safe to pass to msp.SatisfiesPrincipal Type guard
func isConcreteIdentity(id msp.Identity) bool {
_, ok := id.(*msp.Identity) // internal *identity; prefer obtaining ids from the owning MSP
return ok
} Try / catch
if err := msp.SatisfiesPrincipal(id, principal); err != nil {
if strings.Contains(err.Error(), "invalid identity type") {
// reload the identity via msp.DeserializeIdentity and retry once
}
return err
} Prevention
- Always obtain identities from the same MSP that evaluates the principal
- Never wrap or re-implement the Identity interface before passing to SatisfiesPrincipal
- In tests, generate real identities via msp.New instead of mocking the interface
- Keep identity creation and policy evaluation within one MSP manager instance
When it happens
Trigger: Calling msp.SatisfiesPrincipal (or the internal v142 path) with an Identity value that is not the unexported *identity struct returned by this MSP's own methods — for example an identity deserialized/created by a different MSP manager, a test mock implementing fabric.Identity, or a nil/wrong pointer type.
Common situations: Unit tests passing mock identities into SatisfiesPrincipal; mixing identities produced by one MSP provider with another MSP's principal evaluation; wiring a custom identity implementation; accidentally passing an *identitydata or wrapper struct instead of the identity itself.
Related errors
- collection-name: %s -- contains an identity that is not part
- Failed verifying that proposal's creator satisfies local MSP
- failed deserializing identity
- Cannot create signed proposal, due to %s
- failed to serialize signer
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/ed7e9c2d49ec72da.
Report an issue: GitHub.