{"record":{"id":"c0f1dab86699c2c8","repo":"hyperledger/fabric","slug":"bad-payload-and-metadata-tuple","errorCode":null,"errorMessage":"bad payload and metadata tuple","messagePattern":"bad payload and metadata tuple","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"orderer/consensus/smartbft/signature.go","lineNumber":78,"sourceCode":"\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\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":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/orderer/consensus/smartbft/signature.go#L60-L96","documentation":"The proposal Payload is decoded as a ByteBufferTuple (two length-prefixed byte buffers: A=block data, B=block metadata). This error wraps any failure of that tuple decoding, meaning the Payload bytes are not in the expected tuple format.","triggerScenarios":"ProposalToBlock called with a Payload that is not a valid ByteBufferTuple — e.g. raw protobuf block data passed directly instead of the tuple-encoded payload, or Payload bytes corrupted/offset.","commonSituations":"Custom integration code marshalling block data without the ByteBufferTuple wrapper before assigning to Proposal.Payload; byte-offset corruption in storage; messages produced by a mismatched Fabric version using a different payload encoding.","solutions":["Wrap the block payload correctly: encode (blockData, blockMetadata) with ByteBufferTuple.ToBytes before assigning Proposal.Payload.","Re-sync the proposal from other consenters if the local bytes are corrupted.","Align Fabric versions across all orderer nodes so the tuple encoding matches.","Log/inspect the first bytes of Payload to confirm whether it is tuple-encoded before conversion."],"exampleFix":"// before\nprop.Payload = protoutil.MarshalOrPanic(block.Data)\n\n// after\ntuple := &ByteBufferTuple{A: marshalledData, B: marshalledMetadata}\nprop.Payload = tuple.Bytes()","handlingStrategy":"validation","validationCode":"tuple := &ByteBufferTuple{}\nif err := tuple.FromBytes(prop.Payload); err != nil {\n    return fmt.Errorf(\"payload not a valid tuple: %v\", err)\n}\nblock, err := ProposalToBlock(prop)","typeGuard":"func payloadIsTuple(p types.Proposal) bool {\n    t := &ByteBufferTuple{}\n    return t.FromBytes(p.Payload) == nil\n}","tryCatchPattern":"block, err := ProposalToBlock(prop)\nif err != nil && strings.HasPrefix(err.Error(), \"bad payload and metadata tuple\") {\n    // payload encoding mismatch: rebuild tuple or resync\n    return rebuildOrResync(prop)\n}","preventionTips":["Use ByteBufferTuple.ToBytes (not raw marshalling) when filling Proposal.Payload.","Keep Fabric versions aligned across the cluster.","Unit-test proposal encode/decode round-trips in integrations.","Validate tuple layout before persisting custom proposals."],"tags":["hyperledger-fabric","smartbft","encoding","tuple-decode"],"backgroundTag":"payload-decode-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"}