{"record":{"id":"76bc0ae0e7cfff1e","repo":"hyperledger/fabric","slug":"unmarshal-failed","errorCode":null,"errorMessage":"unmarshal failed","messagePattern":"unmarshal failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/chaincode/handler.go","lineNumber":683,"sourceCode":"\t\tCollection: collection,\n\t}\n\n\treadP, writeP, err := txContext.CollectionStore.RetrieveReadWritePermission(cc, txContext.SignedProp, txContext.TXSimulator)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trwPermission := &readWritePermission{read: readP, write: writeP}\n\ttxContext.CollectionACLCache.put(collection, rwPermission)\n\n\treturn rwPermission, nil\n}\n\n// Handles query to ledger to get state\nfunc (h *Handler) HandleGetState(msg *pb.ChaincodeMessage, txContext *TransactionContext) (*pb.ChaincodeMessage, error) {\n\tgetState := &pb.GetState{}\n\terr := proto.Unmarshal(msg.Payload, getState)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"unmarshal failed\")\n\t}\n\n\tvar res []byte\n\tnamespaceID := txContext.NamespaceID\n\tcollection := getState.Collection\n\tchaincodeLogger.Debugf(\"[%s] getting state for chaincode %s, key %s, channel %s\", shorttxid(msg.Txid), namespaceID, getState.Key, txContext.ChannelID)\n\n\tif isCollectionSet(collection) {\n\t\tif txContext.IsInitTransaction {\n\t\t\treturn nil, errors.New(\"private data APIs are not allowed in chaincode Init()\")\n\t\t}\n\t\tif err = errorIfCreatorHasNoReadPermission(namespaceID, collection, txContext); err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\tres, err = txContext.TXSimulator.GetPrivateData(namespaceID, collection, getState.Key)\n\t} else {\n\t\tres, err = txContext.TXSimulator.GetState(namespaceID, getState.Key)\n\t}","sourceCodeStart":665,"sourceCodeEnd":701,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/chaincode/handler.go#L665-L701","documentation":"HandleGetState parses msg.Payload as pb.GetState using proto.Unmarshal; the \"unmarshal failed\" error (wrapped) means the payload bytes are not a valid protobuf GetState message. This is peer-side defense against malformed chaincode-to-peer GET_STATE messages — the request never reaches the ledger.","triggerScenarios":"Chaincode shim sends a GET_STATE message whose payload is empty, truncated, or was serialized with a different/incompatible schema; custom or hand-rolled shim implementations that put wrong bytes in the payload; shim/peer protobuf version mismatch.","commonSituations":"Custom chaincode implementations in non-Go languages hand-building messages; shim and peer versions significantly out of sync; network/transport corruption in experimental setups; tests constructing ChaincodeMessage payloads incorrectly.","solutions":["Use the official fabric-chaincode-go shim (fabric-sdk or language shim) so GetState is serialized as pb.GetState protobuf","Rebuild/redeploy the chaincode with a shim version compatible with the peer's protobuf definitions","If testing peer internals, marshal payload via proto.Marshal(&pb.GetState{Key: ..., Collection: ...})","Check for truncated payloads if messages pass through proxies/custom transports"],"exampleFix":"// before: hand-built payload\npayload := []byte(\"key=mykey\")\n// after\npayload, _ := proto.Marshal(&pb.GetState{Key: \"mykey\"})\nmsg := &pb.ChaincodeMessage{Type: pb.ChaincodeMessage_GET_STATE, Payload: payload, Txid: txid}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func validGetStatePayload(p []byte) bool {\n    var gs pb.GetState\n    return proto.Unmarshal(p, &gs) == nil && gs.Key != \"\"\n}","tryCatchPattern":null,"preventionTips":["Always build GET_STATE payloads with proto.Marshal(&pb.GetState{...})","Keep the shim version aligned with the peer's protobuf definitions","Never hand-assemble protobuf payload bytes in custom shims/tests"],"tags":["hyperledger-fabric","protobuf","serialization","chaincode"],"backgroundTag":"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"}