{"record":{"id":"05b8391debae2423","repo":"hyperledger/fabric","slug":"error-unmarshalling-envelope","errorCode":null,"errorMessage":"error unmarshalling Envelope","messagePattern":"error unmarshalling Envelope","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/txutils.go","lineNumber":54,"sourceCode":"\n\tif pRespPayload.Extension == nil {\n\t\treturn nil, nil, errors.New(\"response payload is missing extension\")\n\t}\n\n\trespPayload, err := UnmarshalChaincodeAction(pRespPayload.Extension)\n\tif err != nil {\n\t\treturn ccPayload, nil, err\n\t}\n\treturn ccPayload, respPayload, nil\n}\n\n// GetEnvelopeFromBlock gets an envelope from a block's Data field.\nfunc GetEnvelopeFromBlock(data []byte) (*common.Envelope, error) {\n\t// Block always begins with an envelope\n\tvar err error\n\tenv := &common.Envelope{}\n\tif err = proto.Unmarshal(data, env); err != nil {\n\t\treturn nil, errors.Wrap(err, \"error unmarshalling Envelope\")\n\t}\n\n\treturn env, nil\n}\n\n// CreateSignedEnvelope creates a signed envelope of the desired type, with\n// marshaled dataMsg and signs it\nfunc CreateSignedEnvelope(\n\ttxType common.HeaderType,\n\tchannelID string,\n\tsigner Signer,\n\tdataMsg proto.Message,\n\tmsgVersion int32,\n\tepoch uint64,\n) (*common.Envelope, error) {\n\treturn CreateSignedEnvelopeWithTLSBinding(txType, channelID, signer, dataMsg, msgVersion, epoch, nil)\n}\n","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/txutils.go#L36-L72","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the underlying wrapped proto error to confirm whether the data is empty, truncated, or a different message type","Verify the bytes came from a real block's Data field (e.g. block.Data.Data[i]) and were not modified or truncated","Check the blockfile/ledger for corruption; re-fetch the block from a healthy peer or restore from snapshot/backup","Confirm peer/orderer and SDK versions are compatible (protobuf wire compatibility)","If constructing test data, build the envelope with protoutil.CreateSignedEnvelope instead of hand-crafting bytes"],"exampleFix":"// before\nenv, err := GetEnvelopeFromBlock(someArbitraryBytes)\n// after\nif len(data) == 0 {\n    return nil, fmt.Errorf(\"empty block data\")\n}\nenv, err := GetEnvelopeFromBlock(data)\nif err != nil {\n    return nil, fmt.Errorf(\"block %d tx %d: %w\", blkNum, txNum, err)\n}","handlingStrategy":"validation","validationCode":"func validateBlockData(data []byte) error {\n    if len(data) == 0 {\n        return fmt.Errorf(\"empty block data\")\n    }\n    env := &common.Envelope{}\n    if err := proto.Unmarshal(data, env); err != nil {\n        return fmt.Errorf(\"not a valid envelope: %w\", err)\n    }\n    return nil\n}","typeGuard":"func isEnvelope(data []byte) bool {\n    env := &common.Envelope{}\n    return proto.Unmarshal(data, env) == nil\n}","tryCatchPattern":"env, err := protoutil.GetEnvelopeFromBlock(data)\nif err != nil {\n    log.Warnf(\"skipping malformed block data: %v\", err)\n    return nil // or fall back to raw-byte handling\n}","preventionTips":["Only feed GetEnvelopeFromBlock bytes taken directly from block.Data.Data entries","Check ledger/blockfile health if the error appears on stored blocks","Keep peer/orderer protobuf versions consistent across components","In tests, build envelopes with protoutil.CreateSignedEnvelope rather than raw bytes"],"tags":["protobuf","unmarshal","hyperledger-fabric","data-corruption"],"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"}