hyperledger/fabric · error

failed verifying that the signed data identity satisfies loc

Error message

failed verifying that the signed data identity satisfies local MSP principal during channelless check policy with policy [%s]: [%s]

What it means

CheckPolicyNoChannelBySignedData evaluates a channelless (local-MSP) policy against signed data. For each SignedData it deserializes the identity with the local MSP and calls id.SatisfiesPrincipal(principal) — the principal being 'Admins' or 'Members' resolved from policyName. This error is returned when the identity is valid for the local MSP but does not satisfy the required principal role (e.g. the signer is a Member but the check required Admins).

Source

Thrown at core/policy/policy.go:218

	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
		}
	}

	return nil
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Sign the proposal with the local MSP admin identity (cryptogen/fabric-ca admin signer for the peer's organization)
  2. Verify the signer's MSP ID matches the peer's local MSP (core.yaml peer.localMspId / MSP config) and that the cert is present in the local MSP admincerts directory
  3. If Members suffices, pass policyName 'Members' instead of 'Admins','or re-enroll/regenerate the admin certificate and restart the peer so the local MSP picks it up

Example fix

// before
signer, _ := mspMgr.GetDefaultSigningIdentity() // member cert
err := checker.CheckPolicyNoChannelBySignedData("Admins", signedData)
// after
adminSigner, _ := adminSignerForLocalMSP(localMSP) // load admincerts-based signing identity
err := checker.CheckPolicyNoChannelBySignedData("Admins", signedData)
Defensive patterns

Strategy: validation

Validate before calling

func canSignAsLocalAdmin(signer msp.SigningIdentity, localMSP msp.MSP) error {
    principal, err := policy.NewLocalMSPPrincipalGetter(localMSP).Get("Admins")
    if err != nil { return err }
    idBytes, _ := signer.Serialize()
    id, err := localMSP.DeserializeIdentity(idBytes)
    if err != nil { return fmt.Errorf("signer not in local MSP: %w", err) }
    return id.SatisfiesPrincipal(principal)
}

Type guard

func isLocalMSPIdentity(localMSP msp.MSP, serializedID []byte) bool {
    _, err := localMSP.DeserializeIdentity(serializedID)
    return err == nil
}

Try / catch

if err := checker.CheckPolicyNoChannelBySignedData(policyName, signedData); err != nil {
    if strings.Contains(err.Error(), "satisfies local MSP principal") {
        // authorization problem: switch to an admin signer, do not retry
        return fmt.Errorf("signer lacks required local role %s: %w", policyName, err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling CheckPolicyNoChannelBySignedData with a policyName of 'Admins' (or 'Members') where the signer's identity belongs to the local MSP but is not in that role: e.g. a non-admin peer or client signs a system-chaincode proposal (like a cscc JoinChain) while local policy requires Admins; also when the identity was serialized by a different MSP than the node's local MSP.

Common situations: A client uses its admin cert from an organization whose MSP differs from the peer's local MSP; admin certs were rotated/regenerated and the old cert no longer satisfies the Admins principal; the caller signs with a TLS cert or member enrollment cert instead of the admin cert; network migration changed MSP IDs so deserialization succeeds via a different path but role membership fails.

Related errors


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