{"record":{"id":"bbc56a0d6c8a52c0","repo":"hyperledger/fabric","slug":"failing-extracting-header-during-channelless-check","errorCode":null,"errorMessage":"Failing extracting header during channelless check policy with policy [%s]: [%s]","messagePattern":"Failing extracting header during channelless check policy with policy \\[(.+?)\\]: \\[(.+?)\\]","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/policy/policy.go","lineNumber":123,"sourceCode":"// CheckPolicyNoChannel checks that the passed signed proposal is valid with the respect to\n// passed policy on the local MSP.\nfunc (p *policyChecker) CheckPolicyNoChannel(policyName string, signedProp *pb.SignedProposal) error {\n\tif policyName == \"\" {\n\t\treturn errors.New(\"Invalid policy name during channelless check policy. Name must be different from nil.\")\n\t}\n\n\tif signedProp == nil {\n\t\treturn fmt.Errorf(\"Invalid signed proposal during channelless check policy with policy [%s]\", policyName)\n\t}\n\n\tproposal, err := protoutil.UnmarshalProposal(signedProp.ProposalBytes)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Failing extracting proposal during channelless check policy with policy [%s]: [%s]\", policyName, err)\n\t}\n\n\theader, err := protoutil.UnmarshalHeader(proposal.Header)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Failing extracting header during channelless check policy with policy [%s]: [%s]\", policyName, err)\n\t}\n\n\tshdr, err := protoutil.UnmarshalSignatureHeader(header.SignatureHeader)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Invalid Proposal's SignatureHeader during channelless check policy with policy [%s]: [%s]\", policyName, err)\n\t}\n\n\t// Deserialize proposal's creator with the local MSP\n\tid, err := p.localMSP.DeserializeIdentity(shdr.Creator)\n\tif err != nil {\n\t\tlogger.Warnw(\"Failed deserializing proposal creator during channelless check policy\", \"error\", err, \"policyName\", policyName, \"identity\", protoutil.LogMessageForSerializedIdentity(shdr.Creator))\n\t\treturn fmt.Errorf(\"Failed deserializing proposal creator during channelless check policy with policy [%s]: [%s]\", policyName, err)\n\t}\n\n\t// Load MSPPrincipal for policy\n\tprincipal, err := p.principalGetter.Get(policyName)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"Failed getting local MSP principal during channelless check policy with policy [%s]: [%s]\", policyName, err)","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/policy/policy.go#L105-L141","documentation":"CheckPolicyNoChannel successfully extracted a Proposal but could not unmarshal proposal.Header into a common.Header protobuf. This means the proposal parsed at the outer layer but its embedded Header field is corrupt or not a serialized Header. The header is required to reach the SignatureHeader and creator identity, so the policy check aborts.","triggerScenarios":"A SignedProposal whose Proposal.Bytes decodes as a Proposal but whose Proposal.Header field holds empty, truncated, or wrongly-typed bytes — typically from custom proposal construction or a payload that was overwritten/repacked after signing.","commonSituations":"Hand-rolled SDK usage that sets Header to nil or to a marshaled SignatureHeader instead of common.Header; test harnesses reusing stale byte slices; schema drift between client and peer protos.","solutions":["Ensure the client sets proposal.Header to protoutil.Marshal(header) of a common.Header (ChannelHeader + SignatureHeader) before signing.","Validate on the client that proposal.Header unmarshals back to a common.Header before sending.","Rebuild the proposal entirely (don't reuse partially-filled structs) to eliminate stale/corrupted fields.","Align protoutil/proto versions between client and peer to rule out wire-format mismatch."],"exampleFix":"// before\nproposal := &common.Proposal{Header: headerStruct}\n\n// after\nhdrBytes, err := protoutil.Marshal(header)\nif err != nil { return err }\nproposal := &common.Proposal{Header: hdrBytes}","handlingStrategy":"validation","validationCode":"if len(proposal.Header) == 0 {\n    return errors.New(\"proposal.Header is empty\")\n}\nif _, err := protoutil.UnmarshalHeader(proposal.Header); err != nil {\n    return fmt.Errorf(\"proposal.Header is not a valid common.Header: %w\", err)\n}","typeGuard":"func hasValidHeader(p *common.Proposal) bool {\n    if p == nil || len(p.Header) == 0 {\n        return false\n    }\n    _, err := protoutil.UnmarshalHeader(p.Header)\n    return err == nil\n}","tryCatchPattern":"err := policyMgr.CheckPolicy(policyName, signedProp)\nif err != nil && strings.Contains(err.Error(), \"Failing extracting header\") {\n    // regenerate the proposal header and re-sign before retrying\n}","preventionTips":["Build common.Header via protoutil utilities instead of manual assembly","Never assign a SignatureHeader or ChannelHeader directly to Proposal.Header — assign marshaled bytes","Validate the full proposal with protoutil.GetHeader / round-trip unmarshal before signing","Avoid mutating proposal structs after signing"],"tags":["hyperledger-fabric","protobuf","proposal-validation"],"backgroundTag":"protobuf-unmarshal-failed","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"}