hyperledger/fabric · error
error unmarshalling Transaction
Error message
error unmarshalling Transaction
What it means
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.
Source
Thrown at protoutil/unmarshalers.go:158
// UnmarshalProposalResponsePayload unmarshals bytes to a ProposalResponsePayload
func UnmarshalProposalResponsePayload(prpBytes []byte) (*peer.ProposalResponsePayload, error) {
prp := &peer.ProposalResponsePayload{}
err := proto.Unmarshal(prpBytes, prp)
return prp, errors.Wrap(err, "error unmarshalling ProposalResponsePayload")
}
// UnmarshalProposal unmarshals bytes to a Proposal
func UnmarshalProposal(propBytes []byte) (*peer.Proposal, error) {
prop := &peer.Proposal{}
err := proto.Unmarshal(propBytes, prop)
return prop, errors.Wrap(err, "error unmarshalling Proposal")
}
// UnmarshalTransaction unmarshals bytes to a Transaction
func UnmarshalTransaction(txBytes []byte) (*peer.Transaction, error) {
tx := &peer.Transaction{}
err := proto.Unmarshal(txBytes, tx)
return tx, errors.Wrap(err, "error unmarshalling Transaction")
}
// UnmarshalChaincodeActionPayload unmarshals bytes to a ChaincodeActionPayload
func UnmarshalChaincodeActionPayload(capBytes []byte) (*peer.ChaincodeActionPayload, error) {
cap := &peer.ChaincodeActionPayload{}
err := proto.Unmarshal(capBytes, cap)
return cap, errors.Wrap(err, "error unmarshalling ChaincodeActionPayload")
}
// UnmarshalChaincodeProposalPayload unmarshals bytes to a ChaincodeProposalPayload
func UnmarshalChaincodeProposalPayload(bytes []byte) (*peer.ChaincodeProposalPayload, error) {
cpp := &peer.ChaincodeProposalPayload{}
err := proto.Unmarshal(bytes, cpp)
return cpp, errors.Wrap(err, "error unmarshalling ChaincodeProposalPayload")
}
// UnmarshalTxReadWriteSet unmarshals bytes to a TxReadWriteSet
func UnmarshalTxReadWriteSet(bytes []byte) (*rwset.TxReadWriteSet, error) {View on GitHub (pinned to 2736b63f8f)
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
Example fix
// before
tx, err := protoutil.UnmarshalTransaction(rawBytes) // may be an Envelope
// after
env, _ := protoutil.UnmarshalEnvelope(rawBytes)
if hdr, _ := protoutil.UnmarshalChannelHeader(env.Payload.Header.ChannelHeader); hdr.Type != int32(common.HeaderType_ENDORSER_TRANSACTION) { return errors.New("not a transaction") }
tx, err := protoutil.UnmarshalTransaction(env.Payload) Defensive patterns
Strategy: validation
Validate before calling
func isEndorserTxBytes(b []byte) bool {
if len(b) == 0 { return false }
env, err := protoutil.UnmarshalEnvelope(b)
if err != nil { return false }
hdr, err := protoutil.ChannelHeader(env.Payload.Header)
if err != nil { return false }
return common.HeaderType(hdr.Type) == common.HeaderType_ENDORSER_TRANSACTION
} Type guard
func safeUnmarshalTransaction(b []byte) (tx *peer.Transaction, ok bool) {
defer func() { if recover() != nil { ok = false } }()
tx, err := protoutil.UnmarshalTransaction(b)
return tx, err == nil && tx != nil
} Try / catch
tx, err := protoutil.UnmarshalTransaction(txBytes)
if err != nil {
var protoErr *proto.UnmarshalError // or inspect wrapped error
log.Debugf("invalid transaction bytes (%d bytes): %v", len(txBytes), err)
return fmt.Errorf("transaction rejected: %w", err)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- GetProposalResponsePayload error %s
- GetChaincodeAction error %s
- error unmarshalling ChaincodeAction
- error unmarshalling ProposalResponsePayload
- error unmarshalling
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/9630a8b7b0766dbb.
Report an issue: GitHub.