hyperledger/fabric · error

certifiersIdentifier does not match: %v, MSP: [%s]

Error message

certifiersIdentifier does not match: %v, MSP: [%s]

What it means

The identity's OU matched a configured NodeOU, but the OU's CertifiersIdentifier (the SKI of the CA that must have issued the certificate) does not match the identifier of the CA that actually signed this identity's certificate. Fabric throws this when NodeOUs specify an OrganizationalUnitIdentifiers restriction and the issuing CA is not one of the allowed certifiers.

Source

Thrown at msp/mspimplvalidate.go:215

	// Make sure that the identity has only one of the special OUs
	// used to tell apart clients or peers.
	counter := 0
	for _, OU := range id.GetOrganizationalUnits() {
		// Is OU.OrganizationalUnitIdentifier one of the special OUs?
		var nodeOU *OUIdentifier
		switch OU.OrganizationalUnitIdentifier {
		case msp.clientOU.OrganizationalUnitIdentifier:
			nodeOU = msp.clientOU
		case msp.peerOU.OrganizationalUnitIdentifier:
			nodeOU = msp.peerOU
		default:
			continue
		}

		// Yes. Then, enforce the certifiers identifier is this is specified.
		// It is not specified, it means that any certification path is fine.
		if len(nodeOU.CertifiersIdentifier) != 0 && !bytes.Equal(nodeOU.CertifiersIdentifier, OU.CertifiersIdentifier) {
			return errors.Errorf("certifiersIdentifier does not match: %v, MSP: [%s]", OUIDs(id.GetOrganizationalUnits()), msp.name)
		}
		counter++
		if counter > 1 {
			break
		}
	}

	// the identity should have exactly one OU role, return an error if the counter is not 1.
	if counter == 0 {
		return errors.Errorf("the identity does not have an OU that resolves to client or peer. OUs: %s, MSP: [%s]", OUIDs(id.GetOrganizationalUnits()), msp.name)
	}
	if counter > 1 {
		return errors.Errorf("the identity must be a client or a peer identity to be valid, not a combination of them. OUs: %s, MSP: [%s]", OUIDs(id.GetOrganizationalUnits()), msp.name)
	}

	return nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Update the NodeOU identifier's Certificate field with the PEM of the CA that actually issued the identity certificates
  2. Reissue the identity certificate using the CA whose SKI matches the configured CertifiersIdentifier
  3. Remove the Certificate field from the OU identifier if any certification path from the MSP is acceptable

Example fix

// before
ClientOUIdentifier:
  OrganizationalUnitIdentifier: client
  Certificate: ca_old.pem
// after: point to the CA that actually signs identities
ClientOUIdentifier:
  OrganizationalUnitIdentifier: client
  Certificate: ca_current.pem
Defensive patterns

Strategy: validation

Validate before calling

import ("crypto/x509")
func certSKI(cert *x509.Certificate) ([]byte, error) {
    for _, ext := range cert.Extensions {
        if ext.Id.String() == "2.5.29.14" {
            var ski []byte
            _, err := asn1.Unmarshal(ext.Value, &ski)
            return ski, err
        }
    }
    return nil, fmt.Errorf("no SKI")
}
// Compare SKI of the configured certifier PEM with the SKI of the CA that
// signed the identity cert before validating.

Prevention

When it happens

Trigger: msp.Validate(identity) with NodeOUs where ClientOUIdentifier/PeerOUIdentifier has a non-empty Certificate (CertifiersIdentifier) field, and bytes.Equal(nodeOU.CertifiersIdentifier, OU.CertifiersIdentifier) fails.

Common situations: Certificate issued by an intermediate/root CA whose Subject Key Identifier differs from the one configured in the NodeOU's certifier PEM; MSP config copied from another network; CA rotated and SKI changed but config not updated.

Related errors


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