hyperledger/fabric · error

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

Error message

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

What it means

V1.4.2 variant of the certifier check: the identity's OU matched a NodeOU, but the OU's CertifiersIdentifier (SKI of the expected issuing CA, taken from the PEM in the NodeOU config) does not equal the CertifiersIdentifier recorded in the identity's OU. Fabric throws this in validateIdentityOUsV142 when a specific certifier is mandated but the certificate came from a different CA.

Source

Thrown at msp/mspimplvalidate.go:274

	}
	if msp.adminOU != nil {
		validOUs[msp.adminOU.OrganizationalUnitIdentifier] = msp.adminOU
	}
	if msp.ordererOU != nil {
		validOUs[msp.ordererOU.OrganizationalUnitIdentifier] = msp.ordererOU
	}

	for _, OU := range id.GetOrganizationalUnits() {
		// Is OU.OrganizationalUnitIdentifier one of the special OUs?
		nodeOU := validOUs[OU.OrganizationalUnitIdentifier]
		if nodeOU == nil {
			continue
		}

		// Yes. Then, enforce the certifiers identifier in this is specified.
		// If 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: %s, 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, peer, orderer, or admin role. OUs: %s, MSP: [%s]", OUIDs(id.GetOrganizationalUnits()), msp.name)
	}
	if counter > 1 {
		return errors.Errorf("the identity must have a client, a peer, an orderer, or an admin OU role 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. Replace the NodeOU identifier Certificate with the correct CA PEM (the one whose SKI equals the OU.CertifiersIdentifier of the identities)
  2. Reissue identities using the CA configured as certifier
  3. Remove the Certificate field if any certifier within the MSP is acceptable

Example fix

// before: mismatch — config lists RootCA but identities signed by IntermediateCA
Certificate: rootca.pem
// after: use the actual issuing CA
Certificate: intermediateca.pem
Defensive patterns

Strategy: validation

Validate before calling

import ("crypto/x509"; "encoding/asn1")
func certifiersMatch(identityCert, configuredCertifierPEM *x509.Certificate) bool {
    var ski []byte
    for _, ext := range configuredCertifierPEM.Extensions {
        if ext.Id.String() == "2.5.29.14" {
            if _, err := asn1.Unmarshal(ext.Value, &ski); err != nil { return false }
        }
    }
    // identityCert must be signed by the CA whose SKI == ski
    return identityCert.CheckSignatureFrom(configuredCertifierPEM) == nil
}

Prevention

When it happens

Trigger: msp.Validate(identity) under V1.4.2 MSP config where nodeOU.CertifiersIdentifier is set (Certificate specified for the OU identifier) and it differs from OU.CertifiersIdentifier derived from the identity's cert chain.

Common situations: Identity signed by intermediate CA while config lists the root (or vice versa); CA certificate rotated; NodeOU Certificate PEM copied from another org's MSP.

Related errors


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