{"record":{"id":"9630a8b7b0766dbb","repo":"hyperledger/fabric","slug":"error-unmarshalling-transaction-9630a8","errorCode":null,"errorMessage":"error unmarshalling Transaction","messagePattern":"error unmarshalling Transaction","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/unmarshalers.go","lineNumber":158,"sourceCode":"// UnmarshalProposalResponsePayload unmarshals bytes to a ProposalResponsePayload\nfunc UnmarshalProposalResponsePayload(prpBytes []byte) (*peer.ProposalResponsePayload, error) {\n\tprp := &peer.ProposalResponsePayload{}\n\terr := proto.Unmarshal(prpBytes, prp)\n\treturn prp, errors.Wrap(err, \"error unmarshalling ProposalResponsePayload\")\n}\n\n// UnmarshalProposal unmarshals bytes to a Proposal\nfunc UnmarshalProposal(propBytes []byte) (*peer.Proposal, error) {\n\tprop := &peer.Proposal{}\n\terr := proto.Unmarshal(propBytes, prop)\n\treturn prop, errors.Wrap(err, \"error unmarshalling Proposal\")\n}\n\n// UnmarshalTransaction unmarshals bytes to a Transaction\nfunc UnmarshalTransaction(txBytes []byte) (*peer.Transaction, error) {\n\ttx := &peer.Transaction{}\n\terr := proto.Unmarshal(txBytes, tx)\n\treturn tx, errors.Wrap(err, \"error unmarshalling Transaction\")\n}\n\n// UnmarshalChaincodeActionPayload unmarshals bytes to a ChaincodeActionPayload\nfunc UnmarshalChaincodeActionPayload(capBytes []byte) (*peer.ChaincodeActionPayload, error) {\n\tcap := &peer.ChaincodeActionPayload{}\n\terr := proto.Unmarshal(capBytes, cap)\n\treturn cap, errors.Wrap(err, \"error unmarshalling ChaincodeActionPayload\")\n}\n\n// UnmarshalChaincodeProposalPayload unmarshals bytes to a ChaincodeProposalPayload\nfunc UnmarshalChaincodeProposalPayload(bytes []byte) (*peer.ChaincodeProposalPayload, error) {\n\tcpp := &peer.ChaincodeProposalPayload{}\n\terr := proto.Unmarshal(bytes, cpp)\n\treturn cpp, errors.Wrap(err, \"error unmarshalling ChaincodeProposalPayload\")\n}\n\n// UnmarshalTxReadWriteSet unmarshals bytes to a TxReadWriteSet\nfunc UnmarshalTxReadWriteSet(bytes []byte) (*rwset.TxReadWriteSet, error) {","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/unmarshalers.go#L140-L176","documentation":"UnmarshalTransaction wraps any protobuf unmarshal failure of raw bytes into a peer.Transaction with this message. The library returns it whenever proto.Unmarshal rejects the input as malformed, truncated, or not a Transaction at all. It signals the caller passed bytes that cannot be interpreted as a peer.Transaction protobuf message.","triggerScenarios":"Calling UnmarshalTransaction with nil or empty bytes, bytes of a different message type (e.g. an Envelope or Payload), corrupted/truncated transaction bytes, or bytes deserialized with the wrong proto definition version.","commonSituations":"Reading a txid from a corrupted block store, passing an envelope's payload instead of a transaction, cross-version Fabric message incompatibility, or feeding hand-crafted bytes in tests.","solutions":["Verify the bytes come from envelope.Payload for a TRANSACTION message (check ChannelHeader.Type == HeaderType_ENDORSER_TRANSACTION) before calling","Log and hex-dump the first bytes of the input to confirm it is non-empty and plausible protobuf data","Ensure the peer/protobuf definitions (fabric-protos) match the version that produced the bytes","Check upstream code for double-unmarshalling: the bytes may already have been consumed or re-wrapped"],"exampleFix":"// before\ntx, err := protoutil.UnmarshalTransaction(rawBytes) // may be an Envelope\n// after\nenv, _ := protoutil.UnmarshalEnvelope(rawBytes)\nif hdr, _ := protoutil.UnmarshalChannelHeader(env.Payload.Header.ChannelHeader); hdr.Type != int32(common.HeaderType_ENDORSER_TRANSACTION) { return errors.New(\"not a transaction\") }\ntx, err := protoutil.UnmarshalTransaction(env.Payload)","handlingStrategy":"validation","validationCode":"func isEndorserTxBytes(b []byte) bool {\n    if len(b) == 0 { return false }\n    env, err := protoutil.UnmarshalEnvelope(b)\n    if err != nil { return false }\n    hdr, err := protoutil.ChannelHeader(env.Payload.Header)\n    if err != nil { return false }\n    return common.HeaderType(hdr.Type) == common.HeaderType_ENDORSER_TRANSACTION\n}","typeGuard":"func safeUnmarshalTransaction(b []byte) (tx *peer.Transaction, ok bool) {\n    defer func() { if recover() != nil { ok = false } }()\n    tx, err := protoutil.UnmarshalTransaction(b)\n    return tx, err == nil && tx != nil\n}","tryCatchPattern":"tx, err := protoutil.UnmarshalTransaction(txBytes)\nif err != nil {\n    var protoErr *proto.UnmarshalError // or inspect wrapped error\n    log.Debugf(\"invalid transaction bytes (%d bytes): %v\", len(txBytes), err)\n    return fmt.Errorf(\"transaction rejected: %w\", err)\n}","preventionTips":["Always extract txBytes from envelope.Payload, never the envelope itself","Check ChannelHeader.Type before interpreting bytes as a transaction","Never feed empty/nil slices to unmarshal helpers; guard len(bytes) > 0","Keep fabric-protos dependencies in sync across all services producing/consuming the bytes"],"tags":["protobuf","unmarshal","fabric","transaction"],"backgroundTag":"proto-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"}