hyperledger/fabric · error

found unknown private key type (%T) in msg signing

Error message

found unknown private key type (%T) in msg signing

What it means

Signer.Sign switches on the concrete type of the loaded private key, supporting *ecdsa.PrivateKey and ed25519.PrivateKey only. If the key is of any other type (e.g. *rsa.PrivateKey), it returns this error. Fabric's signer tooling deliberately restricts supported key algorithms.

Source

Thrown at cmd/common/signer/signer.go:105

		return errors.Errorf("enrollment certificate should be a certificate, got a %s instead", strings.ToLower(bl.Type))
	}

	if _, err := x509.ParseCertificate(bl.Bytes); err != nil {
		return errors.Errorf("enrollment certificate is not a valid x509 certificate: %v", err)
	}
	return nil
}

func (si *Signer) Sign(msg []byte) ([]byte, error) {
	switch key := si.key.(type) {
	// Fabric only supports ECDSA and ed25519 at the moment.
	case *ecdsa.PrivateKey:
		digest := util.ComputeSHA256(msg)
		return signECDSA(si.key.(*ecdsa.PrivateKey), digest)
	case ed25519.PrivateKey:
		return ed25519.Sign(si.key.(ed25519.PrivateKey), msg), nil
	default:
		return nil, errors.Errorf("found unknown private key type (%T) in msg signing", key)
	}
}

func loadPrivateKey(file string) (crypto.PrivateKey, error) {
	b, err := os.ReadFile(file)
	if err != nil {
		return nil, errors.WithStack(err)
	}
	bl, _ := pem.Decode(b)
	if bl == nil {
		return nil, errors.Errorf("failed to decode PEM block from %s", file)
	}
	key, err := parsePrivateKey(bl.Bytes)
	if err != nil {
		return nil, err
	}
	return key, nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Generate/use an ECDSA (P-256) or Ed25519 private key; e.g. openssl ecparam -name prime256v1 -genkey -noout -out key.pem
  2. Re-enroll with Fabric CA using an ECDSA key (csr.cn / key algorithm settings)
  3. Check the key header: 'BEGIN RSA PRIVATE KEY' means unsupported — replace it
  4. If this is a custom type in tests, extend the switch or use a supported key type

Example fix

// before: RSA key
openssl genrsa -out key.pem 2048
// after: ECDSA key
openssl ecparam -name prime256v1 -genkey -noout -out key.pem
Defensive patterns

Strategy: try-catch

Validate before calling

key, err := loadPrivateKey(keyPath)
if err != nil { return err }
switch k := key.(type) {
case *ecdsa.PrivateKey, ed25519.PrivateKey:
default:
    return fmt.Errorf("unsupported key type %T in %s", k, keyPath)
}

Type guard

func isSupportedKey(k crypto.PrivateKey) bool {
    switch k.(type) {
    case *ecdsa.PrivateKey, ed25519.PrivateKey:
        return true
    }
    return false
}

Try / catch

sig, err := signer.Sign(msg)
if err != nil {
    if strings.Contains(err.Error(), "unknown private key type") {
        return fmt.Errorf("replace key with ECDSA/Ed25519: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Creating a Signer whose key file contains an RSA (or other unsupported) private key and calling Sign/Endorse/Send; a test or custom code path injecting a key of unexpected type into Signer.key.

Common situations: Using an RSA key issued by a CA or openssl by mistake instead of an ECDSA key; old materials generated with RSA; Fabric version changes dropping support for other key types.

Related errors


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