hyperledger/fabric · error

no ca certificate found in directory %s

Error message

no ca certificate found in directory %s

What it means

getMspConfig reads <msp-dir>/cacerts to build a verifying MSP; the MSP must trust at least one CA. This error means the cacerts directory was read successfully but contained no certificates, so the organization would trust nothing.

Source

Thrown at msp/configbuilder.go:222

	default:
		return nil, errors.Errorf("unknown MSP type '%s'", mspType)
	}
}

func getMspConfig(dir string, ID string, sigid *msp.SigningIdentityInfo) (*msp.MSPConfig, error) {
	cacertDir := filepath.Join(dir, cacerts)
	admincertDir := filepath.Join(dir, admincerts)
	intermediatecertsDir := filepath.Join(dir, intermediatecerts)
	crlsDir := filepath.Join(dir, crlsfolder)
	configFile := filepath.Join(dir, configfilename)
	tlscacertDir := filepath.Join(dir, tlscacerts)
	tlsintermediatecertsDir := filepath.Join(dir, tlsintermediatecerts)

	cacerts, err := getPemMaterialFromDir(cacertDir)
	if err != nil {
		return nil, errors.WithMessagef(err, "could not load a valid ca certificate from directory %s", cacertDir)
	} else if len(cacerts) == 0 {
		return nil, errors.Errorf("no ca certificate found in directory %s", cacertDir)
	}

	admincert, err := getPemMaterialFromDir(admincertDir)
	if err != nil && !os.IsNotExist(err) {
		return nil, errors.WithMessagef(err, "could not load a valid admin certificate from directory %s", admincertDir)
	}

	intermediatecerts, err := getPemMaterialFromDir(intermediatecertsDir)
	if os.IsNotExist(err) {
		mspLogger.Debugf("Intermediate certs folder not found at [%s]. Skipping. [%s]", intermediatecertsDir, err)
	} else if err != nil {
		return nil, errors.WithMessagef(err, "failed loading intermediate ca certs at [%s]", intermediatecertsDir)
	}

	tlsCACerts, err := getPemMaterialFromDir(tlscacertDir)
	tlsIntermediateCerts := [][]byte{}
	if os.IsNotExist(err) {
		mspLogger.Debugf("TLS CA certs folder not found at [%s]. Skipping and ignoring TLS intermediate CA folder. [%s]", tlsintermediatecertsDir, err)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Copy the org's CA cert PEM into <msp-dir>/cacerts/ and retry
  2. Regenerate crypto material with cryptogen or 'fabric-ca-client enroll' so cacerts is populated
  3. Verify configtx.yaml / the dir argument points at the correct organization MSP directory
  4. Confirm each cacerts file is a valid PEM: 'openssl x509 -in cacerts/*.pem -noout'

Example fix

// before: cacerts empty
$ ls org1.example.com/msp/cacerts   # (empty)
// after
$ cp ca-certs/org1-ca.pem org1.example.com/msp/cacerts/
$ ls org1.example.com/msp/cacerts   # org1-ca.pem
Defensive patterns

Strategy: validation

Validate before calling

func hasCACert(orgMSP string) error {
    certs, err := filepath.Glob(filepath.Join(orgMSP, "cacerts", "*.pem"))
    if err != nil { return err }
    if len(certs) == 0 {
        return fmt.Errorf("%s/cacerts empty: copy the org CA cert PEM", orgMSP)
    }
    for _, c := range certs {
        b, err := os.ReadFile(c)
        if err != nil { return err }
        if pem.Decode(b) == nil { return fmt.Errorf("%s not PEM", c) }
    }
    return nil
}

Try / catch

if err := mspmgmt.GetVerifyingMspConfig(dir, "Org1MSP", "fabric"); err != nil {
    if strings.Contains(err.Error(), "no ca certificate found") {
        return fmt.Errorf("populate %s/cacerts with the org CA cert", dir)
    }
    return err
}

Prevention

When it happens

Trigger: Calling GetVerifyingMspConfig (via createMSP for channel/org config) or getMspConfig with an MSP directory whose cacerts/ folder is empty; also hit by GetLocalMspConfig callers when building the local config path.

Common situations: Org dir generated without cacerts, configtx.yaml pointing to a crypto dir missing the CA certs, MSP copied from another org leaving cacerts empty, certificates deleted during cleanup, container mount missing CA files.

Understand the failure class

Related errors


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