hyperledger/fabric · error
this MSP only supports a single validation chain, got
Error message
this MSP only supports a single validation chain, got %d
What it means
Golang's cert.Verify may return multiple chains if the trust anchors allow more than one path to a root. This MSP requires unambiguous ownership of an identity, so it rejects any identity (or CA) with more than one validation chain, reporting how many chains were found.
Solutions
- Remove duplicate or overlapping certificates from the MSP cacerts and intermediatescerts folders so exactly one chain exists
- Ensure intermediate CA certs are in intermediatescerts, not duplicated in cacerts
- Regenerate the MSP directory with cryptogen or fabric-ca so each cert has a single trust path
- Trim the trust anchor set to only the specific org root that issued the identity
Example fix
// before // cacerts: [rootA.pem, rootB.pem], intermediatescerts: [rootA.pem] -> 2 chains // after // cacerts: [rootA.pem], intermediatescerts: [intermediateA.pem] -> 1 chain
Defensive patterns
Strategy: validation
Validate before calling
// before setup, dedupe trust anchors and ensure roots/intermediates don't overlap:
seen := map[string]bool{}
for _, c := range roots { seen[string(c.Raw)] = true }
for _, c := range intermediates { if seen[string(c.Raw)] { return errors.New("duplicate cert in roots and intermediates") } } Try / catch
err := id.Validate()
if err != nil && strings.Contains(err.Error(), "single validation chain") {
// inspect MSP cert folders for duplicates/overlapping CAs
} Prevention
- Keep cacerts to true root CAs only; never place an intermediate in cacerts
- Deduplicate PEM files across cacerts/intermediatescerts during MSP packaging
- After CA migrations, rebuild the MSP directory rather than incrementally appending certs
When it happens
Trigger: Validating a certificate that chains to the MSP root via two different paths — e.g. the same root CA trust anchor appears in both cacerts and intermediatescerts, or two overlapping root/intermediate CAs both cover the cert's chain — causing len(validationChains) != 1 during validateIdentity/sanitizeCert/finalizeSetupCAs.
Common situations: Copying the same root cert into both the root and intermediate cert folders of the MSP directory; two orgs sharing root CAs; adding redundant trust anchors after a CA migration; Go crypto adding alternative chain paths after trust store changes.
Related errors
- invalid validation chain. Parent certificate should be a…
- An X509 certificate with Basic Constraint: Certificate…
- authorityKeyIdentifier not found in certificate
- certifiersIdentifier does not match
- certifiersIdentifier does not match
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/b5b712ad5f3aa1cb.
Report an issue: GitHub.
Appendix: source
Thrown at msp/mspimpl.go:740
return msp.getValidationChain(id.cert, false)
}
func (msp *bccspmsp) getUniqueValidationChain(cert *x509.Certificate, opts x509.VerifyOptions) ([]*x509.Certificate, error) {
// ask golang to validate the cert for us based on the options that we've built at setup time
if msp.opts == nil {
return nil, errors.New("the supplied identity has no verify options")
}
validationChains, err := cert.Verify(opts)
if err != nil {
return nil, errors.WithMessage(err, "the supplied identity is not valid")
}
// we only support a single validation chain;
// if there's more than one then there might
// be unclarity about who owns the identity
if len(validationChains) != 1 {
return nil, errors.Errorf("this MSP only supports a single validation chain, got %d", len(validationChains))
}
// Make the additional verification checks that were done in Go 1.14.
err = verifyLegacyNameConstraints(validationChains[0])
if err != nil {
return nil, errors.WithMessage(err, "the supplied identity is not valid")
}
return validationChains[0], nil
}
var (
oidExtensionSubjectAltName = asn1.ObjectIdentifier{2, 5, 29, 17}
oidExtensionNameConstraints = asn1.ObjectIdentifier{2, 5, 29, 30}
)
// verifyLegacyNameConstraints exercises the name constraint validation rules
// that were part of the certificate verification process in Go 1.14.View on GitHub (pinned to 2736b63f8f)