hyperledger/fabric · error

Invalid MSPRoleType. It must be CLIENT, PEER, ADMIN or ORDER

Error message

Invalid MSPRoleType. It must be CLIENT, PEER, ADMIN or ORDERER

What it means

bccspmsp.hasOURoleInternal validates an identity against a NodeOUs classification (CLIENT, PEER, ADMIN, ORDERER). This error means the caller passed an m.MSPRole value that is not one of the four supported role types, so the MSP cannot map it to a configured node OU. It is thrown from the default branch of the role switch in msp/mspimpl.go.

Source

Thrown at msp/mspimpl.go:371

		return msp.hasOURoleInternal(id, mspRole)
	default:
		return errors.New("Identity type not recognized")
	}
}

func (msp *bccspmsp) hasOURoleInternal(id *identity, mspRole m.MSPRole_MSPRoleType) error {
	var nodeOU *OUIdentifier
	switch mspRole {
	case m.MSPRole_CLIENT:
		nodeOU = msp.clientOU
	case m.MSPRole_PEER:
		nodeOU = msp.peerOU
	case m.MSPRole_ADMIN:
		nodeOU = msp.adminOU
	case m.MSPRole_ORDERER:
		nodeOU = msp.ordererOU
	default:
		return errors.New("Invalid MSPRoleType. It must be CLIENT, PEER, ADMIN or ORDERER")
	}

	if nodeOU == nil {
		return errors.Errorf("cannot test for classification, node ou for type [%s], not defined, msp: [%s]", mspRole, msp.name)
	}

	for _, OU := range id.GetOrganizationalUnits() {
		if OU.OrganizationalUnitIdentifier == nodeOU.OrganizationalUnitIdentifier {
			return nil
		}
	}

	return errors.Errorf("The identity does not contain OU [%s], MSP: [%s]", mspRole, msp.name)
}

// DeserializeIdentity returns an Identity given the byte-level
// representation of a SerializedIdentity struct
func (msp *bccspmsp) DeserializeIdentity(serializedID []byte) (Identity, error) {

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Set the MSPRole.Role field to one of MSPRole_CLIENT, MSPRole_PEER, MSPRole_ADMIN, or MSPRole_ORDERER before invoking policy evaluation.
  2. If the role came from a policy config, fix the policy YAML/JSON so the node OU role is a valid value (client/peer/admin/orderer).
  3. Check for proto zero-value (MSPRole_MEMBERS / unset) leaking from deserialization and default it explicitly to the intended role.

Example fix

// before
role := &common.MSPRole{} // Role unset (MEMBERS/0)
policy.Principal = role
// after
role := &common.MSPRole{Role: common.MSPRole_CLIENT}
policy.Principal = role
Defensive patterns

Strategy: validation

Validate before calling

var validRoles = map[common.MSPRole_MSPRoleType]bool{
  common.MSPRole_CLIENT: true,
  common.MSPRole_PEER: true,
  common.MSPRole_ADMIN: true,
  common.MSPRole_ORDERER: true,
}
if !validRoles[role.GetRole()] {
  return fmt.Errorf("unsupported MSPRoleType %v; must be CLIENT, PEER, ADMIN or ORDERER", role.GetRole())
}

Type guard

func isValidMSPRole(r common.MSPRole_MSPRoleType) bool {
  return r == common.MSPRole_CLIENT || r == common.MSPRole_PEER ||
    r == common.MSPRole_ADMIN || r == common.MSPRole_ORDERER
}

Prevention

When it happens

Trigger: Calling hasOURole/hasOURoleInternal with an MSPRole proto whose Role field is MSPRole_MEMBERS (or 0/unset, or any value outside CLIENT/PEER/ADMIN/ORDERER), typically via policy principal evaluation (satisfiesPrincipal) with a NODE_OU principal carrying an invalid role.

Common situations: Hand-crafted or corrupted endorsement/ACL policy definitions referencing MSPRoleType values; proto messages deserialized from a newer or older Fabric version with added role types; zero-value MSPRole enums passed programmatically when building principals.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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