hyperledger/fabric · error

no signed data during channelless check policy with policy [

Error message

no signed data during channelless check policy with policy [%s]

What it means

CheckPolicyNoChannelBySignedData requires at least one SignedData entry because each entry's identity is checked against the local MSP principal and its signature verified. An empty (or nil) slice means there is nothing to authorize, so the call fails immediately with this validation error before any MSP work.

Source

Thrown at core/policy/policy.go:197

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

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Ensure at least one SignedData entry with Data, Identity, and Signature populated before calling.
  2. Guard the call: if len(signedData) == 0 { return errors.New("no signed data") }.
  3. Trace why the slice is empty — usually an upstream signing or unmarshalling step failed silently and must be surfaced.
  4. If checking a single proposal, use CheckPolicyNoChannel, which builds its own SignedData from the proposal.

Example fix

// before
var sd []*protoutil.SignedData // never populated
err := policyChecker.CheckPolicyNoChannelBySignedData("Admins", sd)
// after
if len(sd) == 0 {
    return errors.New("cannot check policy: no signed data collected")
}
err := policyChecker.CheckPolicyNoChannelBySignedData("Admins", sd)
Defensive patterns

Strategy: validation

Validate before calling

if len(signedData) == 0 {
    return errors.New("at least one SignedData entry is required for a channelless policy check")
}
err := policyChecker.CheckPolicyNoChannelBySignedData(policyName, signedData)

Type guard

func nonEmptySignedData(sd []*protoutil.SignedData) bool { return len(sd) > 0 }

Prevention

When it happens

Trigger: Calling CheckPolicyNoChannelBySignedData(policyName, nil) or with an empty slice (len(signedData) == 0); commonly when the caller built signed data conditionally and the condition never produced entries, or unmarshalling produced zero entries.

Common situations: Batch code that collects signatures into a slice which ends up empty when all signers fail earlier; tests passing an empty fixture; loops over proposals that were all filtered out, then calling the checker unconditionally with the accumulated (empty) slice.

Related errors


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