hyperledger/fabric · error

failed deserializing signed data identity during channelless

Error message

failed deserializing signed data identity during channelless check policy with policy [%s]: [%s]

What it means

This error occurs when the local MSP cannot deserialize one of the identities in the signed data during a channelless policy check. DeserializeIdentity fails when the identity bytes are not a valid marshaled SerializedIdentity, or the certificate chain does not validate against the peer's local MSP (unknown CA, expired cert, wrong MSP). The wrapped inner error after ': [' names the precise MSP reason.

Source

Thrown at core/policy/policy.go:205

}

// CheckPolicyNoChannelBySignedData checks that the passed signed data are valid with the respect to
// passed policy on the local MSP.
func (p *policyChecker) CheckPolicyNoChannelBySignedData(policyName string, signedData []*protoutil.SignedData) error {
	if policyName == "" {
		return errors.New("invalid policy name during channelless check policy. Name must be different from nil.")
	}

	if len(signedData) == 0 {
		return fmt.Errorf("no signed data during channelless check policy with policy [%s]", policyName)
	}

	for _, data := range signedData {
		// Deserialize identity with the local MSP
		id, err := p.localMSP.DeserializeIdentity(data.Identity)
		if err != nil {
			logger.Warnw("Failed deserializing signed data identity during channelless check policy", "error", err, "policyName", policyName, "identity", protoutil.LogMessageForSerializedIdentity(data.Identity))
			return fmt.Errorf("failed deserializing signed data identity during channelless check policy with policy [%s]: [%s]", policyName, err)
		}

		// Load MSPPrincipal for policy
		principal, err := p.principalGetter.Get(policyName)
		if err != nil {
			return fmt.Errorf("failed getting local MSP principal during channelless check policy with policy [%s]: [%s]", policyName, err)
		}

		// Verify that proposal's creator satisfies the principal
		err = id.SatisfiesPrincipal(principal)
		if err != nil {
			logger.Warnw("failed verifying that the signed data identity satisfies local MSP principal during channelless check policy", "error", err, "policyName", policyName, "requiredPrincipal", principal, "identity", protoutil.LogMessageForSerializedIdentity(data.Identity))
			return fmt.Errorf("failed verifying that the signed data identity satisfies local MSP principal during channelless check policy with policy [%s]: [%s]", policyName, err)
		}

		// Verify the signature
		if err = id.Verify(data.Data, data.Signature); err != nil {
			return err

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Inspect the wrapped MSP error to distinguish 'unknown CA', 'expired', and 'malformed' cases.
  2. Confirm SignedData.Identity is a marshaled SerializedIdentity (creator from a SignatureHeader), not a raw PEM certificate.
  3. Add the signer organization's root/admin certs to the peer's local MSP configuration and restart/reload MSPs.
  4. Re-enroll or re-sign the data with a currently valid identity from an MSP the peer trusts.
  5. Verify both sides use matching Fabric/protobuf versions so identity serialization is compatible.

Example fix

// before: raw PEM cert used as identity
data := &protoutil.SignedData{Data: msg, Identity: certPEM, Signature: sig}
// after: use the marshaled SerializedIdentity from the signature header
shdr, _ := protoutil.UnmarshalSignatureHeader(header.SignatureHeader)
data := &protoutil.SignedData{Data: msg, Identity: shdr.Creator, Signature: sig}
err := policyChecker.CheckPolicyNoChannelBySignedData("Admins", []*protoutil.SignedData{data})
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check: ensure every identity deserializes against the local MSP before the policy call
for i, d := range signedData {
    if _, err := localMSP.DeserializeIdentity(d.Identity); err != nil {
        return fmt.Errorf("signedData[%d] identity not valid for local MSP: %w", i, err)
    }
}

Type guard

func hasDeserializableIdentity(localMSP msp.IdentityDeserializer, d *protoutil.SignedData) bool {
    if d == nil || len(d.Identity) == 0 { return false }
    _, err := localMSP.DeserializeIdentity(d.Identity)
    return err == nil
}

Try / catch

if err := policyChecker.CheckPolicyNoChannelBySignedData(policyName, signedData); err != nil {
    if strings.Contains(err.Error(), "failed deserializing signed data identity") {
        cause := err // inner MSP error after ': [' — check for unknown CA / expired cert
        logger.Warnw("identity rejected by local MSP", "cause", cause)
        return fmt.Errorf("signer identity is not trusted by local MSP (update MSP certs?): %v", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling CheckPolicyNoChannelBySignedData with SignedData.Identity that is empty, corrupt, signed by a cert not in the local MSP, or produced by a different Fabric version's identity format; also when the peer's local MSP config lacks the signer's org's root certs.

Common situations: Client cert rotated/updated but the peer's MSP folder (admincerts/cacerts) not refreshed; identity bytes taken from the wrong field (e.g. raw cert PEM instead of SerializedIdentity proto); cross-org calls where the caller is enrolled in an MSP the peer doesn't trust; mixing fabric-protos legacy bytes with the new protobuf API.

Related errors


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