hyperledger/fabric · error

Failing extracting proposal during check policy with policy

Error message

Failing extracting proposal during check policy with policy [%s]: [%s]

What it means

resourceprovider's CheckACL verifies a signed proposal against a policy. It first unmarshals the proposal bytes using protoutil.UnmarshalProposal; if the bytes are corrupt, truncated, or not a valid Proposal protobuf, evaluation cannot continue and this wrapped error (including policy name and underlying error) is returned.

Source

Thrown at core/aclmgmt/resourceprovider.go:107

// GetPolicyName returns the policy name given the resource string
func (rp *aclmgmtPolicyProviderImpl) GetPolicyName(resName string) string {
	return rp.pEvaluator.PolicyRefForAPI(resName)
}

// CheckACL implements AClProvider's CheckACL interface so it can be registered
// as a provider with aclmgmt
func (rp *aclmgmtPolicyProviderImpl) CheckACL(polName string, idinfo any) error {
	aclLogger.Debugf("acl check(%s)", polName)

	// we will implement other identifiers. In the end we just need a SignedData
	var sd []*protoutil.SignedData
	switch idinfo := idinfo.(type) {
	case *pb.SignedProposal:
		signedProp := idinfo
		proposal, err := protoutil.UnmarshalProposal(signedProp.ProposalBytes)
		if err != nil {
			return fmt.Errorf("Failing extracting proposal during check policy with policy [%s]: [%s]", polName, err)
		}

		header, err := protoutil.UnmarshalHeader(proposal.Header)
		if err != nil {
			return fmt.Errorf("Failing extracting header during check policy [%s]: [%s]", polName, err)
		}

		shdr, err := protoutil.UnmarshalSignatureHeader(header.SignatureHeader)
		if err != nil {
			return fmt.Errorf("Invalid Proposal's SignatureHeader during check policy [%s]: [%s]", polName, err)
		}

		sd = []*protoutil.SignedData{{
			Data:      signedProp.ProposalBytes,
			Identity:  shdr.Creator,
			Signature: signedProp.Signature,
		}}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Fix the client to build ProposalBytes via proto.Marshal of a properly populated protoutil Proposal (use SDK helpers NewProposal).
  2. Verify the payload wasn't modified in transit; check TLS/proxy tampering and recompute the proposal hash/signature.
  3. Check the wrapped underlying error in the message for the specific protobuf failure and align client proto definitions with the peer's protos.
  4. Test with the fabric-sdk or peer CLI to confirm the peer accepts a known-good proposal before debugging custom code.

Example fix

// before
prop := &pb.SignedProposal{ProposalBytes: rawCustomBytes}
// after
proposal, header, err := protoutil.CreateProposalPayload(...)
bytes, _ := proto.Marshal(proposal)
prop := &pb.SignedProposal{ProposalBytes: bytes}
Defensive patterns

Strategy: validation

Validate before calling

var p pb.Proposal
if err := proto.Unmarshal(signedProp.ProposalBytes, &p); err != nil {
    return fmt.Errorf("proposal bytes are not a valid Proposal: %w", err)
}

Type guard

func isValidSignedProposal(sp *pb.SignedProposal) bool {
    var p pb.Proposal
    return sp != nil && len(sp.ProposalBytes) > 0 && proto.Unmarshal(sp.ProposalBytes, &p) == nil
}

Try / catch

if err := aclProvider.CheckACL(resName, channelID, signedProp); err != nil {
    var protoErr error
    if strings.Contains(err.Error(), "Failing extracting proposal") {
        return fmt.Errorf("client built a malformed proposal: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Submitting a SignedProposal whose ProposalBytes field fails protobuf unmarshal — malformed client-built proposals, wrong proto version, or bytes mangled in transit/proxy.

Common situations: Custom clients (SDK or raw gRPC) building SignedProposal with nil or wrongly marshaled ProposalBytes; middleware modifying payloads; cross-version incompatibility between client proto and peer proto.

Related errors


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