{"record":{"id":"5de9715846e6b547","repo":"hyperledger/fabric","slug":"bad-payload-5de971","errorCode":null,"errorMessage":"bad payload","messagePattern":"bad payload","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/signature.go","lineNumber":82,"sourceCode":"\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\n\ttuple := &ByteBufferTuple{}\n\tif err := tuple.FromBytes(proposal.Payload); err != nil {\n\t\treturn nil, errors.Wrap(err, \"bad payload and metadata tuple\")\n\t}\n\n\tif err := proto.Unmarshal(tuple.A, block.Data); err != nil {\n\t\treturn nil, errors.Wrap(err, \"bad payload\")\n\t}\n\n\tif err := proto.Unmarshal(tuple.B, block.Metadata); err != nil {\n\t\treturn nil, errors.Wrap(err, \"bad metadata\")\n\t}\n\treturn block, nil\n}\n\ntype asn1Header struct {\n\tNumber       *big.Int\n\tPreviousHash []byte\n\tDataHash     []byte\n}\n","sourceCodeStart":64,"sourceCodeEnd":96,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/signature.go#L64-L96","documentation":"After decoding the ByteBufferTuple from the proposal Payload, tuple.A is unmarshalled as the block's protobuf BlockData. This error means those bytes are not a valid common.BlockData protobuf message.","triggerScenarios":"ProposalToBlock called where tuple.A of the decoded Payload is corrupt or not a marshalled BlockData — e.g. swapped tuple fields (data/metadata reversed), foreign protobuf bytes, or bit corruption in transit/storage.","commonSituations":"Hand-rolled proposal construction placing the wrong bytes in tuple.A; corrupted WAL/ledger records; a proposal relayed through non-Fabric tooling that re-encoded the bytes.","solutions":["Verify tuple field order: A must be the marshalled block Data, B the marshalled Metadata; swap if reversed.","Discard the proposal and re-synchronize the channel from a healthy quorum of consenters.","Confirm all nodes run a compatible Fabric version producing identical block encoding.","Check storage medium integrity (fsck/SMART) if corruption recurs on the same node."],"exampleFix":"// before\ntuple := &ByteBufferTuple{A: metaBytes, B: dataBytes} // swapped\n\n// after\ntuple := &ByteBufferTuple{A: dataBytes, B: metaBytes}","handlingStrategy":"validation","validationCode":"tuple := &ByteBufferTuple{}\nif err := tuple.FromBytes(prop.Payload); err != nil {\n    return err\n}\nbd := &common.BlockData{}\nif err := proto.Unmarshal(tuple.A, bd); err != nil {\n    return fmt.Errorf(\"tuple.A is not BlockData: %v\", err)\n}\nblock, err := ProposalToBlock(prop)","typeGuard":"func tupleAIsBlockData(p types.Proposal) bool {\n    t := &ByteBufferTuple{}\n    if t.FromBytes(p.Payload) != nil {\n        return false\n    }\n    return proto.Unmarshal(t.A, &common.BlockData{}) == nil\n}","tryCatchPattern":"block, err := ProposalToBlock(prop)\nif err != nil && strings.HasPrefix(err.Error(), \"bad payload\") && !strings.Contains(err.Error(), \"metadata\") {\n    // block data corrupt: discard and resync\n    return resync()\n}","preventionTips":["Keep tuple field order A=data, B=metadata; never swap.","Round-trip test marshal/unmarshal of proposals in CI.","Monitor storage for bit-rot (checksums) on ledger volumes.","Refuse proposals that fail signature verification before decoding."],"tags":["hyperledger-fabric","smartbft","protobuf","decode-failed"],"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"}