{"record":{"id":"daa3d4728756a274","repo":"hyperledger/fabric","slug":"cannot-query-joinbysnapshot-status-due-to-s","errorCode":null,"errorMessage":"cannot query joinbysnapshot status, due to %s","messagePattern":"cannot query joinbysnapshot status, due to (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/peer/channel/joinbysnapshotstatus.go","lineNumber":99,"sourceCode":"\tvar signedProp *pb.SignedProposal\n\tsignedProp, err = protoutil.GetSignedProposal(prop, cc.cf.Signer)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot create signed proposal, due to %s\", err)\n\t}\n\n\tproposalResp, err := cc.cf.EndorserClient.ProcessProposal(context.Background(), signedProp)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed sending proposal, due to %s\", err)\n\t}\n\n\tif proposalResp.Response == nil || proposalResp.Response.Status != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"received bad response, status %d: %s\", proposalResp.Response.Status, proposalResp.Response.Message)\n\t}\n\n\tjoinbysnapshotStatus := &pb.JoinBySnapshotStatus{}\n\terr = proto.Unmarshal(proposalResp.Response.Payload, joinbysnapshotStatus)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot query joinbysnapshot status, due to %s\", err)\n\t}\n\treturn joinbysnapshotStatus, nil\n}\n","sourceCodeStart":81,"sourceCodeEnd":103,"githubUrl":"https://github.com/hyperledger/fabric/blob/2736b63f8fd5932511d56fe68b7039d15977f7f6/internal/peer/channel/joinbysnapshotstatus.go#L81-L103","documentation":"Returned by joinBySnapshotStatus when the payload returned inside a successful (HTTP 200) endorser response cannot be unmarshaled into the JoinBySnapshotStatus protobuf message. This indicates the response bytes are not the expected proto encoding.","triggerScenarios":"proto.Unmarshal(proposalResp.Response.Payload, joinbysnapshotStatus) errors — the peer returned 200 but with empty, truncated, or differently-encoded payload bytes.","commonSituations":"Version mismatch between CLI and peer producing different response shapes; a proxy/middleware corrupting or replacing the payload; peer returning an error string as payload while still reporting 200.","solutions":["Confirm peer and peer CLI binary versions match (same Fabric release line)","Inspect the raw payload in the response for unexpected content","Re-run against the peer directly, bypassing proxies that may rewrite responses","Update both binaries to the latest patch release to align proto definitions"],"exampleFix":"// before: mismatched proto versions -> unmarshal failure\nerr = proto.Unmarshal(proposalResp.Response.Payload, joinbysnapshotStatus)\n// after: guard payload before unmarshaling\nif len(proposalResp.Response.Payload) == 0 {\n    return nil, fmt.Errorf(\"empty payload in endorser response\")\n}\nerr = proto.Unmarshal(proposalResp.Response.Payload, joinbysnapshotStatus)","handlingStrategy":"validation","validationCode":"// pre-flight: payload must be non-empty before unmarshal\nif len(proposalResp.Response.Payload) == 0 {\n    return errors.New(\"endorser returned empty payload for joinbysnapshot status\")\n}","typeGuard":null,"tryCatchPattern":"if err := proto.Unmarshal(proposalResp.Response.Payload, joinbysnapshotStatus); err != nil {\n    return nil, fmt.Errorf(\"cannot query joinbysnapshot status, due to %s\", err)\n}","preventionTips":["Keep CLI and peer on identical Fabric releases so proto shapes align","Bypass mutating proxies between CLI and peer","Log raw payload bytes when unmarshal fails","Regenerate protobuf types from the same .protos as the peer"],"tags":["fabric","protobuf","unmarshal","peer-cli"],"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"}