{"record":{"id":"af9b37b1938da7b5","repo":"hyperledger/fabric","slug":"failing-extracting-proposal-during-check-policy-wi","errorCode":null,"errorMessage":"Failing extracting proposal during check policy with policy [%s]: [%s]","messagePattern":"Failing extracting proposal during check policy with policy \\[(.+?)\\]: \\[(.+?)\\]","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/aclmgmt/resourceprovider.go","lineNumber":107,"sourceCode":"\n// GetPolicyName returns the policy name given the resource string\nfunc (rp *aclmgmtPolicyProviderImpl) GetPolicyName(resName string) string {\n\treturn rp.pEvaluator.PolicyRefForAPI(resName)\n}\n\n// CheckACL implements AClProvider's CheckACL interface so it can be registered\n// as a provider with aclmgmt\nfunc (rp *aclmgmtPolicyProviderImpl) CheckACL(polName string, idinfo any) error {\n\taclLogger.Debugf(\"acl check(%s)\", polName)\n\n\t// we will implement other identifiers. In the end we just need a SignedData\n\tvar sd []*protoutil.SignedData\n\tswitch idinfo := idinfo.(type) {\n\tcase *pb.SignedProposal:\n\t\tsignedProp := idinfo\n\t\tproposal, err := protoutil.UnmarshalProposal(signedProp.ProposalBytes)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Failing extracting proposal during check policy with policy [%s]: [%s]\", polName, err)\n\t\t}\n\n\t\theader, err := protoutil.UnmarshalHeader(proposal.Header)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Failing extracting header during check policy [%s]: [%s]\", polName, err)\n\t\t}\n\n\t\tshdr, err := protoutil.UnmarshalSignatureHeader(header.SignatureHeader)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"Invalid Proposal's SignatureHeader during check policy [%s]: [%s]\", polName, err)\n\t\t}\n\n\t\tsd = []*protoutil.SignedData{{\n\t\t\tData:      signedProp.ProposalBytes,\n\t\t\tIdentity:  shdr.Creator,\n\t\t\tSignature: signedProp.Signature,\n\t\t}}\n","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/aclmgmt/resourceprovider.go#L89-L125","documentation":"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.","triggerScenarios":"Submitting a SignedProposal whose ProposalBytes field fails protobuf unmarshal — malformed client-built proposals, wrong proto version, or bytes mangled in transit/proxy.","commonSituations":"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.","solutions":["Fix the client to build ProposalBytes via proto.Marshal of a properly populated protoutil Proposal (use SDK helpers NewProposal).","Verify the payload wasn't modified in transit; check TLS/proxy tampering and recompute the proposal hash/signature.","Check the wrapped underlying error in the message for the specific protobuf failure and align client proto definitions with the peer's protos.","Test with the fabric-sdk or peer CLI to confirm the peer accepts a known-good proposal before debugging custom code."],"exampleFix":"// before\nprop := &pb.SignedProposal{ProposalBytes: rawCustomBytes}\n// after\nproposal, header, err := protoutil.CreateProposalPayload(...)\nbytes, _ := proto.Marshal(proposal)\nprop := &pb.SignedProposal{ProposalBytes: bytes}","handlingStrategy":"validation","validationCode":"var p pb.Proposal\nif err := proto.Unmarshal(signedProp.ProposalBytes, &p); err != nil {\n    return fmt.Errorf(\"proposal bytes are not a valid Proposal: %w\", err)\n}","typeGuard":"func isValidSignedProposal(sp *pb.SignedProposal) bool {\n    var p pb.Proposal\n    return sp != nil && len(sp.ProposalBytes) > 0 && proto.Unmarshal(sp.ProposalBytes, &p) == nil\n}","tryCatchPattern":"if err := aclProvider.CheckACL(resName, channelID, signedProp); err != nil {\n    var protoErr error\n    if strings.Contains(err.Error(), \"Failing extracting proposal\") {\n        return fmt.Errorf(\"client built a malformed proposal: %w\", err)\n    }\n    return err\n}","preventionTips":["Build proposals with SDK/protoutil helpers (NewProposal) rather than manual byte assembly","Never mutate ProposalBytes after signing; re-sign if payload changes","Keep fabric-protos versions aligned between client and peer","Test against fabric-samples first to isolate client serialization bugs"],"tags":["acl","protobuf","proposal"],"backgroundTag":"invalid-proposal-protobuf","analyzedSha":"2736b63f8fd5932511d56fe68b7039d15977f7f6","analyzedAt":"2026-09-04T08:52:36.465Z","contentChangedAt":"2026-09-04T08:52:36.465Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}