hyperledger/fabric · error
error parsing principal %s
Error message
error parsing principal %s
What it means
When a subject in secondPass is a string, it must match the principal regex ^<MSP_ID>.<ROLE>$ with ROLE one of member|admin|client|peer|orderer. A string that doesn't match (wrong separator, unknown role, spaces, nested-gate text landing in the wrong pass) fails with 'error parsing principal <s>'.
Source
Thrown at common/policydsl/policyparser.go:174
/* sanity check - t should be positive, permit equal to n+1, but disallow over n+1 */
if t < 0 || t > n+1 {
return nil, fmt.Errorf("invalid t-out-of-n predicate, t %d, n %d", t, n)
}
policies := make([]*cb.SignaturePolicy, 0)
/* handle the rest of the arguments */
for _, principal := range args[2:] {
switch t := principal.(type) {
/* if it's a string, we expect it to be formed as
<MSP_ID> . <ROLE>, where MSP_ID is the MSP identifier
and ROLE is either a member, an admin, a client, a peer or an orderer*/
case string:
/* split the string */
subm := regex.FindAllStringSubmatch(t, -1)
if subm == nil || len(subm) != 1 || len(subm[0]) != 4 {
return nil, fmt.Errorf("error parsing principal %s", t)
}
/* get the right role */
var r mb.MSPRole_MSPRoleType
switch subm[0][3] {
case RoleMember:
r = mb.MSPRole_MEMBER
case RoleAdmin:
r = mb.MSPRole_ADMIN
case RoleClient:
r = mb.MSPRole_CLIENT
case RolePeer:
r = mb.MSPRole_PEER
case RoleOrderer:
r = mb.MSPRole_ORDERER
default:
return nil, fmt.Errorf("error parsing role %s", t)View on GitHub (pinned to 2736b63f8f)
Solutions
- Format every principal as '<MSP_ID>.<ROLE>' with a literal dot and lowercase role: 'Org1.member', 'Org1MSP.admin'.
- Use only the supported roles: member, admin, client, peer, orderer.
- Trim whitespace and verify the MSP ID contains only alphanumerics, dots, and dashes.
- If you need a nested gate, wrap it in its gate call (e.g. And('Org1.member','Org2.member')) rather than passing it as a bare string subject.
Example fix
// before
policydsl.FromString("OutOf(1, 'Org1/peer', 'Org2.member')")
// after
policydsl.FromString("OutOf(1, 'Org1.peer', 'Org2.member')") Defensive patterns
Strategy: validation
Validate before calling
var principalRe = regexp.MustCompile(`^([[:alnum:].-]+)\.(member|admin|client|peer|orderer)$`)
func validPrincipal(p string) bool { return principalRe.MatchString(p) }
// check each principal before composing the policy string Type guard
func isPrincipal(s string) bool {
return principalRe.MatchString(s)
} Try / catch
if err != nil && strings.Contains(err.Error(), "error parsing principal") {
return nil, fmt.Errorf("principals must look like 'Org1.member' with role in {member,admin,client,peer,orderer}: %w", err)
} Prevention
- Format principals strictly as <MSP_ID>.<ROLE> with a single dot and lowercase role.
- Only use roles: member, admin, client, peer, orderer.
- Trim whitespace; MSP IDs may only contain alphanumerics, dots, dashes.
- Validate every principal string against the regex before building the policy.
When it happens
Trigger: Principals like 'Org1 Member', 'Org1/peer', 'Org1.owner' (unknown role), or an empty MSP ID ('.member'); also gate keywords ('And', 'or') reaching secondPass as subjects because of malformed nesting in the policy string.
Common situations: Typos in role names ('peers', 'Member' capitalized is actually matched since regex is case-sensitive lowercase — 'Member' fails); using ':' or '/' instead of '.' between MSP ID and role; copying peer CLI -s flag values that aren't principal strings; MSP IDs with characters outside [[:alnum:].-].
Related errors
- MSP for org %s has empty MSP ID
- invalid t-out-of-n predicate, t %d, n %d
- error parsing role %s
- no org found in channel with MSPID '%s'
- Invalid Peer Identity. It must be different from nil.
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/49c71f215dea02fe.
Report an issue: GitHub.