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 errView on GitHub (pinned to 2736b63f8f)
Solutions
- Inspect the wrapped MSP error to distinguish 'unknown CA', 'expired', and 'malformed' cases.
- Confirm SignedData.Identity is a marshaled SerializedIdentity (creator from a SignatureHeader), not a raw PEM certificate.
- Add the signer organization's root/admin certs to the peer's local MSP configuration and restart/reload MSPs.
- Re-enroll or re-sign the data with a currently valid identity from an MSP the peer trusts.
- 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
- Use the marshaled SerializedIdentity (e.g. from SignatureHeader.Creator), never raw PEM bytes.
- Keep the peer's local MSP cacerts/admincerts synchronized with all client organizations' roots.
- Watch certificate expiry and rotate identities before they lapse.
- Align Fabric and protobuf library versions across client and peer.
- Test deserialization of each identity in isolation before running the full policy check.
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
- parseCertificate failed
- public keys do not match
- failed to PEM decode identity bytes: %s
- failed parsing certificate %s
- access denied: channel [%s] creator org [%s]
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/71024a056e1b75b1.
Report an issue: GitHub.