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 MSPView on GitHub (pinned to 2736b63f8f)
Solutions
- Read the wrapped inner error after the last ': [' to identify the real cause (signature mismatch vs principal not satisfied).
- Verify the signature in sd was produced over sd.Data by the private key corresponding to sd.Identity.
- 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).
- Check the peer has the latest channel config/MSP certs; re-fetch channel config and retry with freshly signed data.
- 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
- Always sign exactly the bytes placed in SignedData.Data with the identity's own signing key.
- Keep peer channel config and MSP certs up to date with cert rotations.
- Log the wrapped inner error, not just the wrapper, when diagnosing.
- In tests, build SignedData via the real signing identity (Sign), never with fabricated signatures.
- Verify the named policy exists on the channel (GetPolicy via the manager) before submitting.
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
- failed evaluating policy on signed data during check policy
- orderer org %s attempted to change MSP ID from %s to %s
- application org %s attempted to change MSP ID from %s to %s
- Setup error: unsupported msp type %d
- Attempted to define two different versions of MSP: %s
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/96c6c880e3f863ec.
Report an issue: GitHub.