hyperledger/fabric · error
collection-name: %s -- cannot unmarshal identity bytes into
Error message
collection-name: %s -- cannot unmarshal identity bytes into MSPRole
What it means
During private data collection config validation, each principal in a collection's member-orgs policy is unmarshaled as an MSPRole protobuf. This error is thrown when proto.Unmarshal fails on the principal bytes, meaning the bytes embedded in the MSPPrincipal are not a valid MSPRole message. It almost always indicates a malformed or hand-crafted collection signature policy.
Source
Thrown at core/chaincode/lifecycle/scc.go:867
}
msps, err := mspMgr.GetMSPs()
if err != nil {
return errors.Wrapf(err, "could not get MSPs")
}
// make sure that the orgs listed are actually part of the channel
// check all principals in the signature policy
for _, principal := range coll.MemberOrgsPolicy.GetSignaturePolicy().Identities {
var orgID string
// the member org policy only supports certain principal types
switch principal.PrincipalClassification {
case mspprotos.MSPPrincipal_ROLE:
msprole := &mspprotos.MSPRole{}
err := proto.Unmarshal(principal.Principal, msprole)
if err != nil {
return errors.Wrapf(err, "collection-name: %s -- cannot unmarshal identity bytes into MSPRole", coll.GetName())
}
orgID = msprole.MspIdentifier
// the msp map is indexed using msp IDs - this behavior is implementation specific, making the following check a bit of a hack
_, ok := msps[orgID]
if !ok {
return errors.Errorf("collection-name: %s -- collection member '%s' is not part of the channel", coll.GetName(), orgID)
}
case mspprotos.MSPPrincipal_ORGANIZATION_UNIT:
mspou := &mspprotos.OrganizationUnit{}
err := proto.Unmarshal(principal.Principal, mspou)
if err != nil {
return errors.Wrapf(err, "collection-name: %s -- cannot unmarshal identity bytes into OrganizationUnit", coll.GetName())
}
orgID = mspou.MspIdentifier
// the msp map is indexed using msp IDs - this behavior is implementation specific, making the following check a bit of a hack
_, ok := msps[orgID]
if !ok {View on GitHub (pinned to 2736b63f8f)
Solutions
- Regenerate the collection config with standard tooling (e.g. peer collection JSON -> proto from fabric-samples tooling) instead of hand-crafting the signature policy.
- Verify the MSPPrincipal.Principal bytes are actually a marshaled MSPRole with a MspIdentifier set.
- Confirm the principal classification field matches the payload type (ROLE classification with MSPRole bytes).
- Check the protobuf library version used to serialize the policy matches fabric's expectations.
Example fix
// before (hand-crafted, mismatched payload)
principal := &mspprotos.MSPPrincipal{PrincipalClassification: mspprotos.MSPPrincipal_ROLE, Principal: sigPolicyBytes}
// after
role, _ := proto.Marshal(&mspprotos.MSPRole{MspIdentifier: "Org1MSP", Role: mspprotos.MSPRole_MEMBER})
principal := &mspprotos.MSPPrincipal{PrincipalClassification: mspprotos.MSPPrincipal_ROLE, Principal: role} Defensive patterns
Strategy: validation
Validate before calling
for _, p := range policy.Identities {
if p.PrincipalClassification == mspprotos.MSPPrincipal_ROLE {
var r mspprotos.MSPRole
if err := proto.Unmarshal(p.Principal, &r); err != nil {
return fmt.Errorf("invalid ROLE principal for collection %s: %w", coll.Name, err)
}
}
} Type guard
func isRolePrincipal(p *mspprotos.MSPPrincipal) (*mspprotos.MSPRole, bool) {
if p == nil || p.PrincipalClassification != mspprotos.MSPPrincipal_ROLE {
return nil, false
}
r := &mspprotos.MSPRole{}
if proto.Unmarshal(p.Principal, r) != nil {
return nil, false
}
return r, true
} Try / catch
_, err := proto.Unmarshal(principal.Principal, msprole)
if err != nil {
return fmt.Errorf("collection %s: malformed ROLE principal: %w", collName, err)
} Prevention
- Generate collection configs with standard fabric tooling, never by hand-assembling protobuf bytes.
- Keep principal classification and payload type in sync.
- Deserialize-validate the policy before submitting the chaincode definition.
- Pin protobuf serialization library versions.
When it happens
Trigger: Submitting a chaincode define/approve with a collection config whose member_orgs_policy contains an MSPPrincipal with classification ROLE whose Principal bytes do not decode into an MSPRole (wrong protobuf, corrupted bytes, manually assembled policy).
Common situations: Hand-written collection configs generated by custom tooling instead of configtxgen-style helpers; bytes from a different principal type placed under a ROLE classification; protobuf version mismatch when serializing the policy.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- collection-name: %s -- cannot unmarshal identity bytes into
- collection-name: %s -- collection member '%s' is not part of
- collection-name: %s -- principal type %v is not supported
- signature policy is not an OR concatenation, NOutOf %d
- the proposed collection config does not contain previously d
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/b52eff10caf30269.
Report an issue: GitHub.