{"record":{"id":"1323f35a32a441ca","repo":"hyperledger/fabric","slug":"error-unmarshalling-message-for-type-s","errorCode":null,"errorMessage":"error unmarshalling message for type %s","messagePattern":"error unmarshalling message for type (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"protoutil/commonutils.go","lineNumber":79,"sourceCode":"\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif payload.Header == nil {\n\t\treturn nil, errors.New(\"envelope must have a Header\")\n\t}\n\n\tchdr, err := UnmarshalChannelHeader(payload.Header.ChannelHeader)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif chdr.Type != int32(headerType) {\n\t\treturn nil, errors.Errorf(\"invalid type %s, expected %s\", cb.HeaderType(chdr.Type), headerType)\n\t}\n\n\terr = proto.Unmarshal(payload.Data, message)\n\terr = errors.Wrapf(err, \"error unmarshalling message for type %s\", headerType)\n\treturn chdr, err\n}\n\n// ExtractEnvelopeOrPanic retrieves the requested envelope from a given block\n// and unmarshals it -- it panics if either of these operations fail\nfunc ExtractEnvelopeOrPanic(block *cb.Block, index int) *cb.Envelope {\n\tenvelope, err := ExtractEnvelope(block, index)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn envelope\n}\n\n// ExtractEnvelope retrieves the requested envelope from a given block and\n// unmarshals it\nfunc ExtractEnvelope(block *cb.Block, index int) (*cb.Envelope, error) {\n\tif block.Data == nil {\n\t\treturn nil, errors.New(\"block data is nil\")","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/protoutil/commonutils.go#L61-L97","documentation":"After confirming the header type, UnmarshalEnvelopeOfType unmarshals payload.Data into the caller-supplied proto message; on failure it wraps the underlying proto error with 'error unmarshalling message for type %s'. This means the bytes in the payload do not decode as the expected protobuf message type for that header type.","triggerScenarios":"proto.Unmarshal(payload.Data, message) returns an error — payload.Data holds bytes of a different message type than the header claims, truncated/corrupted data, or the envelope was constructed by hand with wrong Data bytes.","commonSituations":"Corrupted blocks read from file storage (peer's block store), payloads generated by an incompatible Fabric version or an external tool writing malformed protobuf, custom chaincode manually assembling envelopes with incorrectly marshaled Data.","solutions":["Inspect the wrapped inner error (errors.Wrapf preserves it) to identify whether it is truncated data or a wire-type mismatch.","Re-check what component produced the envelope: re-marshal the message with the matching proto type before placing it in payload.Data.","If data came from a block store or snapshot, verify storage integrity / re-fetch the block from the ordering service.","Ensure the peer/orderer/SDK versions agree on the protobuf definitions (fabric-protos) — version skew changes message shapes."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// sanity-check the payload bytes are non-empty before unmarshaling\nif env == nil || len(env.Payload) == 0 {\n    return errors.New(\"envelope has no payload bytes\")\n}\npayload, err := protoutil.UnmarshalPayload(env.Payload)\nif err != nil || len(payload.Data) == 0 {\n    return fmt.Errorf(\"payload missing or empty Data: %w\", err)\n}","typeGuard":"func hasNonEmptyPayloadData(env *cb.Envelope) bool {\n    p, err := protoutil.UnmarshalPayload(env.Payload)\n    return err == nil && p != nil && len(p.Data) > 0\n}","tryCatchPattern":"if err := protoutil.UnmarshalEnvelopeOfType(env, cb.HeaderType_CONFIG, &configEnv); err != nil {\n    logger.Errorf(\"unmarshal failed for %s: %+v\", cb.HeaderType_CONFIG, err) // errors.Wrapf keeps the cause\n    // fall back to re-fetching the block from the ordering service\n    return retryFetch(blockNum)\n}","preventionTips":["Always log errors with %+v so the wrapped proto cause is visible","Marshal payload.Data with the exact proto type named by the header type","Verify ledger/snapshot integrity when blocks come from durable storage","Pin fabric-protos versions to avoid cross-version wire incompatibilities"],"tags":["hyperledger-fabric","protobuf","unmarshal","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"}