{"record":{"id":"6bcb9339fe20cf73","repo":"hyperledger/fabric","slug":"proposal-header-cannot-be-nil","errorCode":null,"errorMessage":"proposal header cannot be nil","messagePattern":"proposal header cannot be nil","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/signature.go","lineNumber":57,"sourceCode":"\treturn bytes\n}\n\n// AsBytes returns the message to sign\nfunc (sig *Signature) AsBytes() []byte {\n\tmsg2Sign := util.ConcatenateBytes(sig.OrdererBlockMetadata, sig.IdentifierHeader, sig.BlockHeader)\n\treturn msg2Sign\n}\n\n// ProposalToBlock marshals the proposal the block\nfunc ProposalToBlock(proposal types.Proposal) (*cb.Block, error) {\n\t// initialize block with empty fields\n\tblock := &cb.Block{\n\t\tData:     &cb.BlockData{},\n\t\tMetadata: &cb.BlockMetadata{},\n\t}\n\n\tif len(proposal.Header) == 0 {\n\t\treturn nil, errors.New(\"proposal header cannot be nil\")\n\t}\n\n\thdr := &asn1Header{}\n\n\tif _, err := asn1.Unmarshal(proposal.Header, hdr); err != nil {\n\t\treturn nil, errors.Wrap(err, \"bad header\")\n\t}\n\n\tblock.Header = &cb.BlockHeader{\n\t\tNumber:       hdr.Number.Uint64(),\n\t\tPreviousHash: hdr.PreviousHash,\n\t\tDataHash:     hdr.DataHash,\n\t}\n\n\tif len(proposal.Payload) == 0 {\n\t\treturn nil, errors.New(\"proposal payload cannot be nil\")\n\t}\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/signature.go#L39-L75","documentation":"ProposalToBlock converts a SmartBFT proposal into a common.Block; the proposal's Header field carries the ASN.1-encoded block header. An empty Header means the proposal is malformed and cannot be converted, so the conversion aborts immediately before any unmarshalling.","triggerScenarios":"Calling VerifyProposal, SignProposal, RequestsFromProposal, or Deliver with a types.Proposal whose Header byte slice is empty/nil — typically a proposal constructed by a different consensus implementation or corrupted during storage/transit.","commonSituations":"Mixing proposal data between RAFT (etcdraft) and SmartBFT channels; reading a corrupted proposal from the WAL/local ledger; a bug in custom consensus integration passing an uninitialized Proposal struct.","solutions":["Confirm the channel is configured with the SmartBFT consensus type and the proposal originates from SmartBFT (check consensus_type in channel config).","Re-pull/re-sync the proposal from correct peers (trigger synchronization) if the local data is corrupted.","Verify no code path passes a zero-value types.Proposal{} into the chain; initialize it from ViewChainer/Consensus state properly.","If upgrading from RAFT, ensure the chain was created with SmartBFT genesis settings rather than reusing RAFT artifacts."],"exampleFix":"// before\nblock, err := signature.ProposalToBlock(types.Proposal{})\n\n// after\nif len(prop.Header) == 0 {\n    return errors.New(\"refusing to convert empty proposal\")\n}\nblock, err := signature.ProposalToBlock(prop)","handlingStrategy":"validation","validationCode":"if prop == nil || len(prop.Header) == 0 {\n    return fmt.Errorf(\"proposal has no header; cannot verify/convert\")\n}\nblock, err := ProposalToBlock(*prop)","typeGuard":"func hasProposalHeader(p *types.Proposal) bool {\n    return p != nil && len(p.Header) > 0\n}","tryCatchPattern":"block, err := ProposalToBlock(prop)\nif err != nil {\n    if err.Error() == \"proposal header cannot be nil\" {\n        // proposal source is invalid; re-fetch or resync\n    }\n    return err\n}","preventionTips":["Never construct types.Proposal from zero values; always populate from consensus state.","Only feed SmartBFT-produced proposals into SmartBFT verification paths.","Validate WAL/backup integrity before replaying proposals.","Add pre-checks for Header/Payload length in custom consensus integrations."],"tags":["hyperledger-fabric","smartbft","proposal","malformed-data"],"backgroundTag":"proposal-header-missing","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"}