hyperledger/fabric · error

identity %s for MSP %s has a non canonical signature

Error message

identity %s for MSP %s has a non canonical signature

What it means

Fabric requires ECDSA signatures in the canonical low-S ASN.1 form produced by utils.MarshalECDSASignature. isIdentitySignedInCanonicalForm re-encodes the identity certificate's signature (r,s) and compares to the original bytes; a mismatch means the signature uses high-S or non-standard DER encoding, which could yield differing identity hashes across crypto libraries, so it is rejected.

Source

Thrown at msp/mspimpl.go:991

		return nil
	}

	return isIdentitySignedInCanonicalForm(cert.Signature, identity.Mspid, identity.IdBytes)
}

func isIdentitySignedInCanonicalForm(sig []byte, mspID string, pemEncodedIdentity []byte) error {
	r, s, err := utils.UnmarshalECDSASignature(sig)
	if err != nil {
		return err
	}

	expectedSig, err := utils.MarshalECDSASignature(r, s)
	if err != nil {
		return err
	}

	if !bytes.Equal(expectedSig, sig) {
		return errors.Errorf("identity %s for MSP %s has a non canonical signature",
			string(pemEncodedIdentity), mspID)
	}

	return nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Re-issue/re-enroll the certificate with the Fabric CA (fabric-ca-client) so the signature is canonical
  2. Re-sign the certificate with an ECDSA CA configured to produce low-S signatures (Go crypto does this by default)
  3. Convert the offending cert by re-issuing from the same key via the fabric CA — the signature bytes cannot be safely patched by hand
  4. If it is a CA certificate issue, regenerate the CA with cryptogen/fabric-ca and redistribute the chain

Example fix

// before
// cert signed by custom OpenSSL CA with high-S ECDSA signature
// after
fabric-ca-client enroll -u http://ca:7054 -M msp  # re-enroll, canonical sig
Defensive patterns

Strategy: validation

Validate before calling

// reject certs whose ECDSA signature is not low-S before enrollment
sig := cert.Signature
// verify signature parses and has S in lower half of order via crypto/ecdsa + math/big
if new(big.Int).Cmp(s, new(big.Int).Rsh(curveN, 1)) > 0 { return errors.New("high-S signature") }

Try / catch

if err := msp.IsWellFormed(si); err != nil {
	if strings.Contains(err.Error(), "non canonical signature") {
		// re-issue cert with fabric-ca (Go crypto emits low-S)
	}
	return err
}

Prevention

When it happens

Trigger: IsWellFormed calls isIdentitySignedInCanonicalForm, which fails when the ECDSA signature on the identity certificate is not in the canonical low-S DER encoding — typically a certificate produced by non-Fabric tooling or an unusual CA.

Common situations: Importing certificates generated by OpenSSL/other CAs with high-S signatures into a Fabric MSP; older crypto libraries emitting non-canonical DER; crypto material copied from a non-Hyperledger CA.

Related errors


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