{"record":{"id":"74802109dec648e2","repo":"hyperledger/fabric","slug":"certifiersidentifier-does-not-match-s-msp-s","errorCode":null,"errorMessage":"certifiersIdentifier does not match: %s, MSP: [%s]","messagePattern":"certifiersIdentifier does not match: (.+?), MSP: \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"msp/mspimplvalidate.go","lineNumber":274,"sourceCode":"\t}\n\tif msp.adminOU != nil {\n\t\tvalidOUs[msp.adminOU.OrganizationalUnitIdentifier] = msp.adminOU\n\t}\n\tif msp.ordererOU != nil {\n\t\tvalidOUs[msp.ordererOU.OrganizationalUnitIdentifier] = msp.ordererOU\n\t}\n\n\tfor _, OU := range id.GetOrganizationalUnits() {\n\t\t// Is OU.OrganizationalUnitIdentifier one of the special OUs?\n\t\tnodeOU := validOUs[OU.OrganizationalUnitIdentifier]\n\t\tif nodeOU == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\t// Yes. Then, enforce the certifiers identifier in this is specified.\n\t\t// If is not specified, it means that any certification path is fine.\n\t\tif len(nodeOU.CertifiersIdentifier) != 0 && !bytes.Equal(nodeOU.CertifiersIdentifier, OU.CertifiersIdentifier) {\n\t\t\treturn errors.Errorf(\"certifiersIdentifier does not match: %s, MSP: [%s]\", OUIDs(id.GetOrganizationalUnits()), msp.name)\n\t\t}\n\t\tcounter++\n\t\tif counter > 1 {\n\t\t\tbreak\n\t\t}\n\t}\n\n\t// the identity should have exactly one OU role, return an error if the counter is not 1.\n\tif counter == 0 {\n\t\treturn 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)\n\t}\n\tif counter > 1 {\n\t\treturn 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)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":256,"sourceCodeEnd":292,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/msp/mspimplvalidate.go#L256-L292","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Replace the NodeOU identifier Certificate with the correct CA PEM (the one whose SKI equals the OU.CertifiersIdentifier of the identities)","Reissue identities using the CA configured as certifier","Remove the Certificate field if any certifier within the MSP is acceptable"],"exampleFix":"// before: mismatch — config lists RootCA but identities signed by IntermediateCA\nCertificate: rootca.pem\n// after: use the actual issuing CA\nCertificate: intermediateca.pem","handlingStrategy":"validation","validationCode":"import (\"crypto/x509\"; \"encoding/asn1\")\nfunc certifiersMatch(identityCert, configuredCertifierPEM *x509.Certificate) bool {\n    var ski []byte\n    for _, ext := range configuredCertifierPEM.Extensions {\n        if ext.Id.String() == \"2.5.29.14\" {\n            if _, err := asn1.Unmarshal(ext.Value, &ski); err != nil { return false }\n        }\n    }\n    // identityCert must be signed by the CA whose SKI == ski\n    return identityCert.CheckSignatureFrom(configuredCertifierPEM) == nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Update NodeOU Certificate whenever CAs rotate","List the exact issuing CA in the OU identifier, not an unrelated org's CA","Diff MSP config.yaml against the org's source-of-truth after upgrades"],"tags":["fabric","msp","x509","pki"],"backgroundTag":"certifier-identifier-mismatch","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}