hyperledger/fabric · error

no signing certificate found in directory %s

Error message

no signing certificate found in directory %s

What it means

GetLocalMspConfig requires exactly the local node's signing certificate; this error means the signcerts directory was read successfully but contained zero PEM certificates. The node has no identity cert, so a local MSP cannot be constructed.

Source

Thrown at msp/configbuilder.go:183

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

func GetLocalMspConfig(dir string, bccspConfig *factory.FactoryOpts, ID string) (*msp.MSPConfig, error) {
	signcertDir := filepath.Join(dir, signcerts)
	keystoreDir := filepath.Join(dir, keystore)
	bccspConfig = SetupBCCSPKeystoreConfig(bccspConfig, keystoreDir)

	err := factory.InitFactories(bccspConfig)
	if err != nil {
		return nil, errors.WithMessage(err, "could not initialize BCCSP Factories")
	}

	signcert, err := getPemMaterialFromDir(signcertDir)
	if err != nil {
		return nil, errors.Wrapf(err, "could not load signing certificate from directory %s", signcertDir)
	} else if len(signcert) == 0 {
		return nil, errors.Errorf("no signing certificate found in directory %s", signcertDir)
	}

	/* FIXME: for now we're making the following assumptions
	1) there is exactly one signing cert
	2) BCCSP's KeyStore has the private key that matches SKI of
	   signing cert
	*/

	sigid := &msp.SigningIdentityInfo{PublicSigner: signcert[0], PrivateSigner: nil}

	return getMspConfig(dir, ID, sigid)
}

// GetVerifyingMspConfig returns an MSP config given directory, ID and type
func GetVerifyingMspConfig(dir, ID, mspType string) (*msp.MSPConfig, error) {
	switch mspType {
	case ProviderTypeToString(FABRIC):
		return getMspConfig(dir, ID, nil)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Copy the signed node certificate into <msp-dir>/signcerts/ (e.g. from fabric-ca-client's Signcerts dir after enroll)
  2. Re-run 'fabric-ca-client enroll' or 'cryptogen generate' to produce the signing cert
  3. Verify signcerts is non-empty: 'ls <msp-dir>/signcerts/*.pem'
  4. Check that Core peer.tls/cert config points to the correct MSP root

Example fix

// before: signcerts empty
$ ls msp/signcerts   # (empty)
// after
$ cp msp/keystore/../Signcerts/cert.pem msp/signcerts/cert.pem
$ ls msp/signcerts   # cert.pem
Defensive patterns

Strategy: validation

Validate before calling

func hasSigningCert(mspRoot string) error {
    files, err := filepath.Glob(filepath.Join(mspRoot, "signcerts", "*.pem"))
    if err != nil { return err }
    if len(files) == 0 {
        return fmt.Errorf("%s/signcerts is empty: run fabric-ca-client enroll or cryptogen first", mspRoot)
    }
    return nil
}

Try / catch

if err := InitCrypto(bsp, mspPath, mspID); err != nil {
    if strings.Contains(err.Error(), "no signing certificate found") {
        return fmt.Errorf("enroll node or copy cert into %s/signcerts", mspPath)
    }
    return err
}

Prevention

When it happens

Trigger: Calling GetLocalMspConfig/GetLocalMspConfigWithType (via InitCrypto) against an MSP directory whose signcerts/ folder is empty — no cert has been enrolled/copied yet, or only a private key exists in keystore.

Common situations: Fresh fabric-ca enroll output mis-organized (cert left in keystore or copekeystore), MSP dir copied without signcerts, stale mounted volume wiped at container start, forgotten cryptogen step.

Understand the failure class

Related errors


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