hyperledger/fabric · error

error unmarshalling Envelope

Error message

error unmarshalling Envelope

What it means

GetEnvelopeFromBlock wraps any protobuf unmarshal failure that occurs while decoding a block's Data field into a common.Envelope. It means the raw bytes passed in are not a valid serialized protobuf Envelope — the data is corrupted, truncated, or not an envelope at all. The library wraps the underlying proto error with this message to give context about which decode step failed.

Source

Thrown at protoutil/txutils.go:54

	if pRespPayload.Extension == nil {
		return nil, nil, errors.New("response payload is missing extension")
	}

	respPayload, err := UnmarshalChaincodeAction(pRespPayload.Extension)
	if err != nil {
		return ccPayload, nil, err
	}
	return ccPayload, respPayload, nil
}

// GetEnvelopeFromBlock gets an envelope from a block's Data field.
func GetEnvelopeFromBlock(data []byte) (*common.Envelope, error) {
	// Block always begins with an envelope
	var err error
	env := &common.Envelope{}
	if err = proto.Unmarshal(data, env); err != nil {
		return nil, errors.Wrap(err, "error unmarshalling Envelope")
	}

	return env, nil
}

// CreateSignedEnvelope creates a signed envelope of the desired type, with
// marshaled dataMsg and signs it
func CreateSignedEnvelope(
	txType common.HeaderType,
	channelID string,
	signer Signer,
	dataMsg proto.Message,
	msgVersion int32,
	epoch uint64,
) (*common.Envelope, error) {
	return CreateSignedEnvelopeWithTLSBinding(txType, channelID, signer, dataMsg, msgVersion, epoch, nil)
}

View on GitHub (pinned to 2736b63f8f)

Solutions

  1. Inspect the underlying wrapped proto error to confirm whether the data is empty, truncated, or a different message type
  2. Verify the bytes came from a real block's Data field (e.g. block.Data.Data[i]) and were not modified or truncated
  3. Check the blockfile/ledger for corruption; re-fetch the block from a healthy peer or restore from snapshot/backup
  4. Confirm peer/orderer and SDK versions are compatible (protobuf wire compatibility)
  5. If constructing test data, build the envelope with protoutil.CreateSignedEnvelope instead of hand-crafting bytes

Example fix

// before
env, err := GetEnvelopeFromBlock(someArbitraryBytes)
// after
if len(data) == 0 {
    return nil, fmt.Errorf("empty block data")
}
env, err := GetEnvelopeFromBlock(data)
if err != nil {
    return nil, fmt.Errorf("block %d tx %d: %w", blkNum, txNum, err)
}
Defensive patterns

Strategy: validation

Validate before calling

func validateBlockData(data []byte) error {
    if len(data) == 0 {
        return fmt.Errorf("empty block data")
    }
    env := &common.Envelope{}
    if err := proto.Unmarshal(data, env); err != nil {
        return fmt.Errorf("not a valid envelope: %w", err)
    }
    return nil
}

Type guard

func isEnvelope(data []byte) bool {
    env := &common.Envelope{}
    return proto.Unmarshal(data, env) == nil
}

Try / catch

env, err := protoutil.GetEnvelopeFromBlock(data)
if err != nil {
    log.Warnf("skipping malformed block data: %v", err)
    return nil // or fall back to raw-byte handling
}

Prevention

When it happens

Trigger: Calling GetEnvelopeFromBlock with bytes read from a block's Data field that are not a valid proto-marshaled common.Envelope, e.g. garbage bytes, an empty slice, truncated data, or a payload of a different message type.

Common situations: Corrupt ledger/block files (truncated blockfile writes), manually constructed test blocks with non-envelope payloads, deserializing data fetched from a different channel or peer version whose Data encoding differs, or passing raw chaincode/transaction bytes instead of envelope bytes.

Understand the failure class

Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.

Related errors


AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04). Data as JSON: /api/errors/05b8391debae2423. Report an issue: GitHub.