hyperledger/fabric · error

failed to parse certificate

Error message

failed to parse certificate

What it means

ExtractPublicKeyFromCert parses raw DER certificate bytes with x509.ParseCertificate and wraps any failure with this message before marshaling the public key. It is the DER-level entry point, unlike VerifySignature which takes PEM.

Source

Thrown at orderer/common/cluster/util.go:835

		if height >= maxHeight {
			maxHeight = height
			mostUpToDateEndpoint = endpoint
		}
	}
	return mostUpToDateEndpoint, maxHeight, nil
}

func EncodeTimestamp(t *timestamppb.Timestamp) []byte {
	b := make([]byte, 8)
	binary.LittleEndian.PutUint64(b, uint64(t.Seconds))
	return b
}

// ExtractPublicKeyFromCert extracts the public key from an X.509 certificate
func ExtractPublicKeyFromCert(der []byte) ([]byte, error) {
	cert, err := x509.ParseCertificate(der)
	if err != nil {
		return nil, errors.Wrap(err, "failed to parse certificate")
	}

	return x509.MarshalPKIXPublicKey(cert.PublicKey)
}

func CompareCertPublicKeys(cert1, cert2 []byte) (bool, error) {
	// Extract public key using the same approach as IsConsenterOfChannel
	bl, _ := pem.Decode(cert1)
	if bl == nil {
		return false, errors.Errorf("node identity certificate %s is not a valid PEM", string(cert1))
	}

	publicKey1, err := ExtractPublicKeyFromCert(bl.Bytes)
	if err != nil {
		return false, err
	}

	bl, _ = pem.Decode(cert2)

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Pass only the DER payload (the Bytes field of the pem.Block), not the PEM-encoded text
  2. Validate the cert with openssl x509 -inform DER before calling
  3. Read the wrapped inner error to identify the specific ASN.1 problem and re-export the certificate if corrupted
  4. If starting from PEM, decode first: blk, _ := pem.Decode(data); use blk.Bytes

Example fix

// before
pk, err := ExtractPublicKeyFromCert(pemFileBytes) // PEM text, not DER
// after
blk, _ := pem.Decode(pemFileBytes)
pk, err := ExtractPublicKeyFromCert(blk.Bytes)
Defensive patterns

Strategy: validation

Validate before calling

if len(der) == 0 { return errors.New("empty DER input") }
if _, err := x509.ParseCertificate(der); err != nil {
    return fmt.Errorf("not a valid DER certificate: %w", err)
}

Type guard

func isDERCertificate(der []byte) bool {
    _, err := x509.ParseCertificate(der)
    return err == nil
}

Try / catch

pk, err := cluster.ExtractPublicKeyFromCert(der)
if err != nil && strings.Contains(err.Error(), "failed to parse certificate") {
    return fmt.Errorf("pass DER bytes (pemBlock.Bytes), not PEM text: %w", err)
}

Prevention

When it happens

Trigger: Passing malformed DER bytes, a PEM block's Bytes taken incorrectly, or a certificate with an encoding the local x509 parser rejects (unknown critical extension, truncated ASN.1) into ExtractPublicKeyFromCert or CompareCertPublicKeys.

Common situations: Caller passed a full PEM file (with BEGIN/END headers) instead of bare DER (bl.Bytes); certificates generated by non-Go tooling with unusual encodings; corrupted cert storage.

Understand the failure class

Related errors


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