hyperledger/fabric · critical
CA Certificate did not have the CA attribute, (SN: %x)
Error message
CA Certificate did not have the CA attribute, (SN: %x)
What it means
finalizeSetupCAs validates that every root and intermediate CA identity's certificate has the BasicConstraints CA flag set (cert.IsCA). A certificate in cacerts/ or intermediatecerts/ without CA:true is rejected because it cannot properly sign or validate chains.
Source
Thrown at msp/mspimplsetup.go:255
crl.SignatureValue = asn1.BitString{Bytes: sig, BitLength: 8 * len(sig)}
}
// TODO: pre-verify the signature on the CRL and create a map
// of CA certs to respective CRLs so that later upon
// validation we can already look up the CRL given the
// chain of the certificate to be validated
msp.CRL[i] = crl
}
return nil
}
func (msp *bccspmsp) finalizeSetupCAs() error {
// ensure that our CAs are properly formed and that they are valid
for _, id := range append(append([]Identity{}, msp.rootCerts...), msp.intermediateCerts...) {
if !id.(*identity).cert.IsCA {
return errors.Errorf("CA Certificate did not have the CA attribute, (SN: %x)", id.(*identity).cert.SerialNumber)
}
if _, err := getSubjectKeyIdentifierFromCert(id.(*identity).cert); err != nil {
return errors.WithMessagef(err, "CA Certificate problem with Subject Key Identifier extension, (SN: %x)", id.(*identity).cert.SerialNumber)
}
if err := msp.validateCAIdentity(id.(*identity)); err != nil {
return errors.WithMessagef(err, "CA Certificate is not valid, (SN: %s)", id.(*identity).cert.SerialNumber)
}
}
// populate certificationTreeInternalNodesMap to mark the internal nodes of the
// certification tree
msp.certificationTreeInternalNodesMap = make(map[string]bool)
for _, id := range append([]Identity{}, msp.intermediateCerts...) {
chain, err := msp.getUniqueValidationChain(id.(*identity).cert, msp.getValidityOptsForCert(id.(*identity).cert))
if err != nil {
return errors.WithMessagef(err, "failed getting validation chain, (SN: %s)", id.(*identity).cert.SerialNumber)
}View on GitHub (pinned to 2736b63f8f)
Solutions
- Replace the certificate in cacerts/intermediatecerts with a real CA certificate that has basicConstraints CA:TRUE
- Re-generate the CA with openssl req -x509 (which sets CA:true) or fabric-ca-server init
- Check with: openssl x509 -in cert.pem -text | grep -A1 'Basic Constraints'
- If intending an intermediate CA, issue it from the root with CA:TRUE extension
Example fix
// before: leaf cert (CA:FALSE) in msp/cacerts/ // after: proper CA cert // openssl req -x509 -new -nodes -key ca.key -sha256 -days 365 \ // -subj '/CN=Org1 CA' -addext 'basicConstraints=critical,CA:TRUE' -out ca.crt null
Defensive patterns
Strategy: validation
Validate before calling
for _, c := range caCerts {
if !c.IsCA {
return fmt.Errorf("cert %s lacks CA basic constraint", c.Subject)
}
if c.KeyUsage&x509.KeyUsageCertSign == 0 {
return fmt.Errorf("cert %s lacks certSign key usage", c.Subject)
}
} Type guard
func isCACert(c *x509.Certificate) bool {
return c.IsCA && c.KeyUsage&x509.KeyUsageCertSign != 0
} Prevention
- Verify basicConstraints CA:TRUE on every cert placed in cacerts/intermediatecerts
- Never copy admin/client certs into CA directories
- Generate CAs with -x509 self-signed issuance that includes CA constraints
When it happens
Trigger: A certificate placed in the MSP's cacerts or intermediatecerts (loaded via setupCAs into rootCerts/intermediateCerts, sanitized, then finalized) has IsCA=false — i.e., an end-entity certificate used as a CA.
Common situations: Copying an admin/client certificate into cacerts by mistake; generating a CA without the CA basic constraint extension; a misconfigured fabric-ca or openssl CSR where basicConstraints CA:true was omitted; TestMalformedCertsChainSetup exercising this path in tests.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- public keys do not match
- failed to PEM decode identity bytes: %s
- failed parsing certificate %s
- failed unmarshaling ECDSA signature on identity: %s
- failed deserializing signed data identity during channelless
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/447bba4a9229620a.
Report an issue: GitHub.