hyperledger/fabric · error
collection-name: %s -- cannot unmarshal identity bytes into
Error message
collection-name: %s -- cannot unmarshal identity bytes into OrganizationUnit
What it means
For ORGANIZATION_UNIT-class principals in a collection member orgs policy, the principal bytes are unmarshaled into an OrganizationUnit protobuf. This error is thrown when that unmarshal fails, meaning the bytes are not a valid OrganizationUnit message. It indicates a malformed collection signature policy.
Source
Thrown at core/chaincode/lifecycle/scc.go:880
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 {
return errors.Errorf("collection-name: %s -- collection member '%s' is not part of the channel", coll.GetName(), orgID)
}
case mspprotos.MSPPrincipal_IDENTITY:
if _, err := mspMgr.DeserializeIdentity(principal.Principal); err != nil {
return errors.Errorf("collection-name: %s -- contains an identity that is not part of the channel", coll.GetName())
}
default:
return errors.Errorf("collection-name: %s -- principal type %v is not supported", coll.GetName(), principal.PrincipalClassification)
}
}
return nilView on GitHub (pinned to 2736b63f8f)
Solutions
- Marshal a proper mspprotos.OrganizationUnit (MspIdentifier, OrganizationalUnitIdentifier, CertifiersIdentifier) and use those bytes.
- Prefer ROLE principals, which are simpler and the common pattern for collections.
- Validate the generated policy by deserializing it before submitting the chaincode definition.
- Regenerate the collection config with standard tooling.
Example fix
// before
principal := &mspprotos.MSPPrincipal{PrincipalClassification: mspprotos.MSPPrincipal_ORGANIZATION_UNIT, Principal: []byte("Org1/unit1")}
// after
ou, _ := proto.Marshal(&mspprotos.OrganizationUnit{MspIdentifier: "Org1MSP", OrganizationalUnitIdentifier: "unit1"})
principal := &mspprotos.MSPPrincipal{PrincipalClassification: mspprotos.MSPPrincipal_ORGANIZATION_UNIT, Principal: ou} Defensive patterns
Strategy: validation
Validate before calling
if p.PrincipalClassification == mspprotos.MSPPrincipal_ORGANIZATION_UNIT {
var ou mspprotos.OrganizationUnit
if err := proto.Unmarshal(p.Principal, &ou); err != nil {
return fmt.Errorf("invalid ORGANIZATION_UNIT principal: %w", err)
}
} Type guard
func isOUPrincipal(p *mspprotos.MSPPrincipal) (*mspprotos.OrganizationUnit, bool) {
if p == nil || p.PrincipalClassification != mspprotos.MSPPrincipal_ORGANIZATION_UNIT {
return nil, false
}
ou := &mspprotos.OrganizationUnit{}
if proto.Unmarshal(p.Principal, ou) != nil {
return nil, false
}
return ou, true
} Try / catch
defer func() {
if r := recover(); r != nil { /* handle malformed policy construction */ }
}()
// or on submission:
if err := submit(); err != nil {
if strings.Contains(err.Error(), "cannot unmarshal identity bytes into OrganizationUnit") {
// rebuild policy with marshaled OrganizationUnit bytes
}
} Prevention
- Always proto.Marshal an OrganizationUnit before placing it in a principal.
- Prefer ROLE principals, which cover most collection use cases.
- Round-trip (marshal then unmarshal) test policies before submission.
- Never reuse principal bytes across different classifications.
When it happens
Trigger: A collection config member_orgs_policy principal with classification ORGANIZATION_UNIT whose Principal bytes are not a marshaled OrganizationUnit protobuf.
Common situations: Custom policy-building code stuffing raw strings or wrong message types into the Principal field; copying policy bytes between different classification types; corrupted serialized policies.
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/762d147e753c0b93.
Report an issue: GitHub.