hyperledger/fabric · error
failed marshaling ECDSA signature
Error message
failed marshaling ECDSA signature
What it means
SanitizeX509Cert re-signs/re-encodes an X.509 certificate and rebuilds the ECDSA signature via utils.MarshalECDSASignature. If converting the r/s big integers back to an ASN.1 DER-encoded ECDSA-Sig-Value fails, this wrapped error is returned. It indicates the signature components produced from the original certificate could not be marshaled.
Source
Thrown at common/crypto/sanitize.go:75
// We assume that the consenter and the CA use the same signature scheme.
curveOrderUsedByCryptoGen := cert.PublicKey.(*ecdsa.PublicKey).Curve.Params().N
halfOrder := new(big.Int).Rsh(curveOrderUsedByCryptoGen, 1)
// Low S, nothing to do here!
if s.Cmp(halfOrder) != 1 {
return initialPEM, nil
}
// Else it's high-S, so shift it below half the order.
s.Sub(curveOrderUsedByCryptoGen, s)
var newCert certificate
_, err = asn1.Unmarshal(cert.Raw, &newCert)
if err != nil {
return nil, errors.Wrapf(err, "failed unmarshaling certificate")
}
newSig, err := utils.MarshalECDSASignature(r, s)
if err != nil {
return nil, errors.Wrapf(err, "failed marshaling ECDSA signature")
}
newCert.SignatureValue = asn1.BitString{Bytes: newSig, BitLength: len(newSig) * 8}
newCert.Raw = nil
newRaw, err := asn1.Marshal(newCert)
if err != nil {
return nil, errors.Wrapf(err, "failed marshaling new certificate")
}
finalPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: newRaw})
return finalPEM, nil
}
type certificate struct {
Raw asn1.RawContent
TBSCertificate tbsCertificate
SignatureAlgorithm pkix.AlgorithmIdentifier
SignatureValue asn1.BitStringView on GitHub (pinned to 2736b63f8f)
Solutions
- Verify the input certificate is a valid, well-formed x509 certificate (run openssl x509 -in cert.pem -text -noout)
- Check utils.MarshalECDSASignature for constraints on r/s (e.g., disallowing zero values) and ensure the cert's signature passes them
- Regenerate the certificate/key pair; the source cert may be corrupted
Example fix
// before
pemBytes, err := crypto.SanitizeX509Cert(corruptedCertPEM)
// after
if _, err := x509.ParseCertificate(pemBlock.Bytes); err != nil {
return fmt.Errorf("invalid cert input: %w", err) // validate before sanitizing
}
pemBytes, err := crypto.SanitizeX509Cert(validCertPEM) Defensive patterns
Strategy: validation
Validate before calling
block, _ := pem.Decode(certPEM)
if block == nil {
return errors.New("input is not valid PEM")
}
if _, err := x509.ParseCertificate(block.Bytes); err != nil {
return fmt.Errorf("invalid certificate: %w", err)
} Try / catch
pem, err := crypto.SanitizeX509Cert(certPEM)
if err != nil {
if strings.Contains(err.Error(), "failed marshaling ECDSA signature") {
return fmt.Errorf("certificate signature components are malformed: %w", err)
}
return err
} Prevention
- Only sanitize certificates that parse cleanly with x509.ParseCertificate first
- Keep fabric/utils and crypto libraries at matching versions
- Reject corrupted or hand-edited PEM files early in the pipeline
When it happens
Trigger: Calling SanitizeX509Cert (directly or via SanitizeIdentity, ConfigureNodeCerts, IsChannelMember) on a certificate whose extracted signature r/s values fail ASN.1 marshaling in utils.MarshalECDSASignature.
Common situations: Parsing a non-standard or corrupted certificate whose signature fields are malformed; negative or zero signature components; corrupted PEM input.
Related errors
- failed marshaling new certificate
- found unknown private key type (%T) in msg signing
- failed parsing certificate %s
- failed unmarshaling certificate
- %s: wrong PEM encoding
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/a5339faf2c112985.
Report an issue: GitHub.