hyperledger/fabric · error

%s: wrong PEM encoding

Error message

%s: wrong PEM encoding

What it means

Raised in getSigningIdentityFromConf while importing the private key from the KeyMaterial fallback field: the KeyMaterial bytes could not be PEM-decoded into a usable private key. BCCSP could not find the key by SKI in its keystore, and the inline KeyMaterial in the config is empty, corrupted, or not a PEM-encoded key.

Source

Thrown at msp/mspimpl.go:240

	// Extract the public part of the identity
	idPub, pubKey, err := msp.getIdentityFromConf(sidInfo.PublicSigner)
	if err != nil {
		return nil, err
	}

	// Find the matching private key in the BCCSP keystore
	privKey, err := msp.bccsp.GetKey(pubKey.SKI())
	// Less Secure: Attempt to import Private Key from KeyInfo, if BCCSP was not able to find the key
	if err != nil {
		mspLogger.Debugf("Could not find SKI [%s], trying KeyMaterial field: %+v\n", hex.EncodeToString(pubKey.SKI()), err)
		if sidInfo.PrivateSigner == nil || sidInfo.PrivateSigner.KeyMaterial == nil {
			return nil, errors.New("KeyMaterial not found in SigningIdentityInfo")
		}

		pemKey, _ := pem.Decode(sidInfo.PrivateSigner.KeyMaterial)
		if pemKey == nil {
			return nil, errors.Errorf("%s: wrong PEM encoding", sidInfo.PrivateSigner.KeyIdentifier)
		}
		privKey, err = msp.bccsp.KeyImport(pemKey.Bytes, &bccsp.ECDSAPrivateKeyImportOpts{Temporary: true})
		if err != nil {
			return nil, errors.WithMessage(err, "getIdentityFromBytes error: Failed to import EC private key")
		}
	}

	// get the peer signer
	peerSigner, err := signer.New(msp.bccsp, privKey)
	if err != nil {
		return nil, errors.WithMessage(err, "getIdentityFromBytes error: Failed initializing bccspCryptoSigner")
	}

	return newSigningIdentity(idPub.(*identity).cert, idPub.(*identity).pk, peerSigner, msp)
}

// Setup sets up the internal data structures
// for this MSP, given an MSPConfig ref; it

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. PEM-encode the private key (-----BEGIN PRIVATE KEY-----) before setting KeyMaterial
  2. Round-trip validate: pem.Decode the value in a unit test before configuring the MSP
  3. If relying on the keystore instead, fix the SKI lookup so this fallback path is never taken

Example fix

// before
KeyMaterial: derKeyBytes
// after
KeyMaterial: pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: derKeyBytes})
Defensive patterns

Strategy: validation

Validate before calling

if blk, _ := pem.Decode(info.PrivateSigner.KeyMaterial); blk == nil {
    return fmt.Errorf("key %s: KeyMaterial is not PEM-encoded", info.PrivateSigner.KeyIdentifier)
}

Type guard

func pemDecodable(b []byte) (*pem.Block, bool) {
    blk, _ := pem.Decode(b)
    return blk, blk != nil
}

Try / catch

if err := msp.Setup(conf); err != nil && strings.Contains(err.Error(), "wrong PEM encoding") {
    return fmt.Errorf("re-embed the private key as PEM: %w", err)
}

Prevention

When it happens

Trigger: SigningIdentityInfo.PrivateSigner.KeyMaterial containing raw DER key bytes, an empty non-nil slice, or a non-key PEM block while the SKI lookup also missed the keystore.

Common situations: Storing the key base64-only (no BEGIN/END lines); pasting an encrypted PKCS#8 blob with damaged armor; a generator that forgot to PEM-encode the key before embedding.

Related errors


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