hyperledger/fabric · error

Failed evaluating policy on signed data during check policy

Error message

Failed evaluating policy on signed data during check policy on channel [%s] with policy [%s]: [%s]

What it means

This error is returned by CheckPolicyBySignedData when the channel policy retrieved for policyName fails to evaluate against the supplied SignedData. It is a wrapper: the real cause (signature verification failure, identity not satisfying the policy principals, missing signatures, etc.) is embedded in the [%s] suffix from policy.EvaluateSignedData. The policy object itself was found (GetPolicy never returns a usable error here), so this failure is purely about evaluation, not policy lookup.

Source

Thrown at core/policy/policy.go:183

	if sd == nil {
		return fmt.Errorf("Invalid signed data during check policy on channel [%s] with policy [%s]", channelID, policyName)
	}

	// Get Policy
	policyManager := p.channelPolicyManagerGetter.Manager(channelID)
	if policyManager == nil {
		return fmt.Errorf("Failed to get policy manager for channel [%s]", channelID)
	}

	// Recall that get policy always returns a policy object
	policy, _ := policyManager.GetPolicy(policyName)

	// Evaluate the policy
	err := policy.EvaluateSignedData(sd)
	if err != nil {
		logger.Warnw("Failed evaluating policy on signed data", "error", err, "policyName", policyName, "identities", protoutil.LogMessageForSerializedIdentities(sd))
		return fmt.Errorf("Failed evaluating policy on signed data during check policy on channel [%s] with policy [%s]: [%s]", channelID, policyName, err)
	}

	return nil
}

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

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Read the wrapped inner error after the last ': [' to identify the real cause (signature mismatch vs principal not satisfied).
  2. Verify the signature in sd was produced over sd.Data by the private key corresponding to sd.Identity.
  3. Confirm sd.Identity deserializes in the channel's MSP and the identity's role satisfies the named policy (e.g. member of an org listed in Writers).
  4. Check the peer has the latest channel config/MSP certs; re-fetch channel config and retry with freshly signed data.
  5. If constructing SignedData manually in tests, sign protoutil.NewSignatureHeader-based bytes with the actual creator's signing identity via signingIdentity.Sign(data).

Example fix

// before: signature over wrong bytes
sd := &protoutil.SignedData{Data: proposalBytes, Identity: creator, Signature: sigOverSomethingElse}
err := pc.CheckPolicyBySignedData(channelID, "Writers", []*protoutil.SignedData{sd})
// after: sign the exact data with the creator's signing identity
sig, err := signingIdentity.Sign(proposalBytes)
if err != nil { return err }
sd := &protoutil.SignedData{Data: proposalBytes, Identity: creator, Signature: sig}
err = pc.CheckPolicyBySignedData(channelID, "Writers", []*protoutil.SignedData{sd})
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: validate inputs and confirm identities/signatures before calling
if channelID == "" || policyName == "" || sd == nil { return errors.New("invalid arguments to CheckPolicyBySignedData") }
for _, d := range sd {
    if _, err := mspManager.DeserializeIdentity(d.Identity); err != nil {
        return fmt.Errorf("identity not in channel MSP: %w", err)
    }
}

Type guard

func validSignedData(sd []*protoutil.SignedData) bool {
    if len(sd) == 0 { return false }
    for _, d := range sd {
        if d == nil || len(d.Data) == 0 || len(d.Identity) == 0 || len(d.Signature) == 0 { return false }
    }
    return true
}

Try / catch

if err := policyChecker.CheckPolicyBySignedData(channelID, policyName, sd); err != nil {
    var policyErr error
    if strings.Contains(err.Error(), "Failed evaluating policy on signed data") {
        // log full error: the wrapped cause after ': [' carries the real reason
        logger.Errorf("policy evaluation rejected signed data: %v", err)
        policyErr = fmt.Errorf("submitter does not satisfy policy %s on channel %s", policyName, channelID)
    }
    return policyErr
}

Prevention

When it happens

Trigger: Calling CheckPolicy (or CheckPolicyBySignedData directly, e.g. in tests like TestCheckPolicyBySignedDataInvalidArgs) with valid channelID/policyName/non-nil sd, but the sd identities do not satisfy the channel policy (e.g. Writers/Readers), signatures are invalid or stale, or the signed data was built from an envelope signed by a cert not in the channel MSP.

Common situations: Endorsement/transaction validation where the submitter's cert was rotated or removed from the channel config; a proposal signed with a different key than the creator identity; testing with fabricated SignedData whose signature doesn't match; invoking a system chaincode policy (e.g. '又能Writers') with data from a peer whose MSP config is out of date.

Related errors


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