hyperledger/fabric · error

cannot test for classification, node ou for type [%s], not d

Error message

cannot test for classification, node ou for type [%s], not defined, msp: [%s]

What it means

After mapping the requested MSPRole to a node OU, hasOURoleInternal checks whether that OU is configured in the MSP (clientOU/peerOU/adminOU/ordererOU). This error means the role is valid but the MSP configuration does not define the corresponding NodeOUs entry, so classification cannot be tested. It is a configuration-gap error in msp/mspimpl.go.

Source

Thrown at msp/mspimpl.go:375

}

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) {
	mspLogger.Debug("Obtaining identity")

	// We first deserialize to a SerializedIdentity to get the MSP ID
	sId := &m.SerializedIdentity{}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Add the missing NodeOUs entry (e.g. AdminOUIdentifiers) to the MSP's config.yaml and redeploy the MSP directory.
  2. Enable NodeOUs: set NodeOUs.Enable: true and provide OUIdentifiers for all roles you evaluate policies against.
  3. If the role classification isn't needed, change the policy principal to one backed by a defined OU (e.g. PEER) or use an explicit MSPRole/MSP member principal instead.

Example fix

# before (config.yaml)
NodeOUs:
  Enable: true
  ClientOUIdentifier:
    Certificate: cacerts/cert.pem
    OrganizationalUnitIdentifier: client
# after
NodeOUs:
  Enable: true
  ClientOUIdentifier:
    Certificate: cacerts/cert.pem
    OrganizationalUnitIdentifier: client
  AdminOUIdentifier:
    Certificate: cacerts/cert.pem
    OrganizationalUnitIdentifier: admin
Defensive patterns

Strategy: validation

Validate before calling

func mspDefinesNodeOU(cfg *msp.MSPConfig, role string) bool {
  var conf m.FabricMSPConfig
  if err := proto.Unmarshal(cfg.Config, &conf); err != nil {
    return false
  }
  if conf.NodeOus == nil {
    return false
  }
  switch role {
  case "client":
    return conf.NodeOus.ClientOuIdentifier != nil
  case "peer":
    return conf.NodeOus.PeerOuIdentifier != nil
  case "admin":
    return conf.NodeOus.AdminOuIdentifier != nil
  case "orderer":
    return conf.NodeOus.OrdererOuIdentifier != nil
  }
  return false
}

Prevention

When it happens

Trigger: Evaluating a NODE_OU principal for a role (e.g. ADMIN) while the MSP config's NodeOUs section omits that OU (or NodeOUs/OUIdentifiers are not enabled at all in config.yaml), via hasOURole during policy satisfaction checks.

Common situations: config.yaml lacking the NodeOUs block or the specific AdminOUIdentifiers/OrdererOUIdentifiers entries; upgrading a network that now uses NodeOUs-based ACLs while old MSP dirs have no NodeOUs; typo'd OU identifiers meaning the section was skipped.

Related errors


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