{"record":{"id":"a625ad063d6cb882","repo":"hyperledger/fabric","slug":"failed-to-unmarshal-snapshot-request","errorCode":null,"errorMessage":"failed to unmarshal snapshot request","messagePattern":"failed to unmarshal snapshot request","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/ledger/snapshotgrpc/snapshot_service.go","lineNumber":44,"sourceCode":"\tLedgerGetter LedgerGetter\n\tACLProvider  ACLProvider\n}\n\n// LedgerGetter gets the PeerLedger associated with a channel.\ntype LedgerGetter interface {\n\tGetLedger(cid string) ledger.PeerLedger\n}\n\n// ACLProvider checks ACL for a channelless resource\ntype ACLProvider interface {\n\tCheckACLNoChannel(resName string, idinfo any) error\n}\n\n// Generate generates a snapshot request.\nfunc (s *SnapshotService) Generate(ctx context.Context, signedRequest *pb.SignedSnapshotRequest) (*emptypb.Empty, error) {\n\trequest := &pb.SnapshotRequest{}\n\tif err := proto.Unmarshal(signedRequest.Request, request); err != nil {\n\t\treturn nil, errors.Wrap(err, \"failed to unmarshal snapshot request\")\n\t}\n\n\tif err := s.checkACL(resources.Snapshot_submitrequest, request.SignatureHeader, signedRequest); err != nil {\n\t\treturn nil, err\n\t}\n\n\tlgr, err := s.getLedger(request.ChannelId)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := lgr.SubmitSnapshotRequest(request.BlockNumber); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &emptypb.Empty{}, nil\n}\n","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/core/ledger/snapshotgrpc/snapshot_service.go#L26-L62","documentation":"SnapshotService.Generate first proto-unmarshals the raw bytes of the SignedSnapshotRequest. If the Request bytes are not a valid pb.SnapshotRequest message, the underlying unmarshal error is wrapped with 'failed to unmarshal snapshot request' and returned. The request never reaches the ACL check.","triggerScenarios":"Sending Generate a signed request whose .Request field is nil, empty, truncated, or serialized with the wrong message type (e.g. a SnapshotQuery instead of SnapshotRequest, or a JSON body instead of protobuf).","commonSituations":"Client SDKs building the request manually with wrong field encoding; middleware/base64 corruption when relaying the signed request; version mismatch where client and peer protobuf definitions differ; tests posting empty payloads.","solutions":["Regenerate the request using protoutil/SnapshotRequest marhsaling helpers so .Request holds valid protobuf bytes.","Confirm the client and peer use matching .proto definitions for SnapshotRequest (same protobuf version).","Check any transport encoding (base64/compression) is not truncating the payload.","Log proto.Unmarshal's wrapped cause — it names the exact byte-offset failure for diagnosis."],"exampleFix":"// before\nreq := &pb.SnapshotRequest{SignatureHeader: hdr}\nsigned := &pb.SignedSnapshotRequest{Request: []byte(fmt.Sprintf(\"%v\", req))}\n// after\nraw, _ := proto.Marshal(req)\nsigned := &pb.SignedSnapshotRequest{Request: raw, Signature: sig}","handlingStrategy":"validation","validationCode":"var probe pb.SnapshotRequest\nif err := proto.Unmarshal(signedReq.Request, &probe); err != nil {\n    return fmt.Errorf(\"client-side check: request payload is not a valid SnapshotRequest: %w\", err)\n}\nresp, err := svc.Generate(ctx, signedReq)","typeGuard":"func isValidSnapshotRequest(raw []byte) bool {\n    var r pb.SnapshotRequest\n    return proto.Unmarshal(raw, &r) == nil\n}","tryCatchPattern":"resp, err := svc.Generate(ctx, signedReq)\nif err != nil {\n    if strings.Contains(err.Error(), \"failed to unmarshal snapshot request\") {\n        // re-marshal payload with proto.Marshal and retry once\n    }\n    return err\n}","preventionTips":["Always build payloads with proto.Marshal on the correct message type.","Pin matching protobuf/schema versions between client and peer.","Unit-test the marshal→unmarshal round trip for request builders."],"tags":["grpc","protobuf","snapshot","unmarshal"],"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"}