hyperledger/fabric · error
failed to unmarshal snapshot request
Error message
failed to unmarshal snapshot request
What it means
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.
Source
Thrown at core/ledger/snapshotgrpc/snapshot_service.go:44
LedgerGetter LedgerGetter
ACLProvider ACLProvider
}
// LedgerGetter gets the PeerLedger associated with a channel.
type LedgerGetter interface {
GetLedger(cid string) ledger.PeerLedger
}
// ACLProvider checks ACL for a channelless resource
type ACLProvider interface {
CheckACLNoChannel(resName string, idinfo any) error
}
// Generate generates a snapshot request.
func (s *SnapshotService) Generate(ctx context.Context, signedRequest *pb.SignedSnapshotRequest) (*emptypb.Empty, error) {
request := &pb.SnapshotRequest{}
if err := proto.Unmarshal(signedRequest.Request, request); err != nil {
return nil, errors.Wrap(err, "failed to unmarshal snapshot request")
}
if err := s.checkACL(resources.Snapshot_submitrequest, request.SignatureHeader, signedRequest); err != nil {
return nil, err
}
lgr, err := s.getLedger(request.ChannelId)
if err != nil {
return nil, err
}
if err := lgr.SubmitSnapshotRequest(request.BlockNumber); err != nil {
return nil, err
}
return &emptypb.Empty{}, nil
}
View on GitHub (pinned to 2736b63f8f)
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.
Example fix
// before
req := &pb.SnapshotRequest{SignatureHeader: hdr}
signed := &pb.SignedSnapshotRequest{Request: []byte(fmt.Sprintf("%v", req))}
// after
raw, _ := proto.Marshal(req)
signed := &pb.SignedSnapshotRequest{Request: raw, Signature: sig} Defensive patterns
Strategy: validation
Validate before calling
var probe pb.SnapshotRequest
if err := proto.Unmarshal(signedReq.Request, &probe); err != nil {
return fmt.Errorf("client-side check: request payload is not a valid SnapshotRequest: %w", err)
}
resp, err := svc.Generate(ctx, signedReq) Type guard
func isValidSnapshotRequest(raw []byte) bool {
var r pb.SnapshotRequest
return proto.Unmarshal(raw, &r) == nil
} Try / catch
resp, err := svc.Generate(ctx, signedReq)
if err != nil {
if strings.Contains(err.Error(), "failed to unmarshal snapshot request") {
// re-marshal payload with proto.Marshal and retry once
}
return err
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
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
- error unmarshalling
- error unmarshalling original config
- error unmarshalling updated config
- Error unmarshalling to SignaturePolicy: %s
- failed to deserialize values
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/a625ad063d6cb882.
Report an issue: GitHub.