{"record":{"id":"f48d186522fd3bff","repo":"grpc/grpc-go","slug":"lrs-unexpected-message-type-t","errorCode":null,"errorMessage":"lrs: unexpected message type %T","messagePattern":"lrs: unexpected message type %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"internal/xds/clients/lrsclient/lrs_stream.go","lineNumber":214,"sourceCode":"}\n\n// recvFirstLoadStatsResponse receives the first LoadStatsResponse from the LRS\n// server.  Returns the following:\n//   - a list of cluster names requested by the server or an empty slice if the\n//     server requested for load from all clusters\n//   - the load reporting interval, and\n//   - any error encountered\nfunc (lrs *streamImpl) recvFirstLoadStatsResponse(stream clients.Stream) ([]string, time.Duration, error) {\n\tr, err := stream.Recv()\n\tif err != nil {\n\t\treturn nil, 0, fmt.Errorf(\"lrs: failed to receive first LoadStatsResponse: %v\", err)\n\t}\n\tvar resp v3lrspb.LoadStatsResponse\n\tif err := proto.Unmarshal(r, &resp); err != nil {\n\t\tif lrs.logger.V(2) {\n\t\t\tlrs.logger.Infof(\"Failed to unmarshal response to LoadStatsResponse: %v\", err)\n\t\t}\n\t\treturn nil, time.Duration(0), fmt.Errorf(\"lrs: unexpected message type %T\", r)\n\t}\n\tif lrs.logger.V(perRPCVerbosityLevel) {\n\t\tlrs.logger.Infof(\"Received first LoadStatsResponse: %s\", pretty.ToJSON(&resp))\n\t}\n\n\tinternal := resp.GetLoadReportingInterval()\n\tif internal.CheckValid() != nil {\n\t\treturn nil, 0, fmt.Errorf(\"lrs: invalid load_reporting_interval: %v\", err)\n\t}\n\tloadReportingInterval := internal.AsDuration()\n\n\tclusters := resp.Clusters\n\tif resp.SendAllClusters {\n\t\t// Return an empty slice to send stats for all clusters.\n\t\tclusters = []string{}\n\t}\n\n\treturn clusters, loadReportingInterval, nil","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/grpc/grpc-go/blob/0c51461d27177d997e14c642fe18c11668fc09a3/internal/xds/clients/lrsclient/lrs_stream.go#L196-L232","documentation":"Returned by recvFirstLoadStatsResponse when the bytes received from the server cannot be unmarshaled into a LoadStatsResponse (lrs_stream.go:214). The implementation reports this as an unexpected message type even though the root cause is a protobuf unmarshal failure.","triggerScenarios":"stream.Recv() succeeds but proto.Unmarshal(r, &v3lrspb.LoadStatsResponse{}) fails - typically because the server sent a v2 message, a wrong-type response, or corrupted bytes. The function then returns fmt.Errorf(\"lrs: unexpected message type %T\", r).","commonSituations":"Server and client disagree on the LRS proto version (v2 vs v3); the endpoint is not actually LRS (e.g. it returned a DiscoveryResponse); a buggy server serializes the wrong message type on the StreamLoadStats method.","solutions":["Confirm both client and server implement the v3 LRS service (envoy.service.load_stats.v3).","Capture traffic (or raise perRPCVerbosityLevel logging) to inspect the actual bytes received.","Point the client at the correct LRS endpoint/method."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Ensure the server implements the v3 LRS service (envoy.service.load_stats.v3).","Version-test the server with grpcurl against the StreamLoadStats method before going live.","Keep client and control-plane proto versions in sync."],"tags":["lrs","xds","protobuf","version-mismatch","stream"],"backgroundTag":null,"analyzedSha":"0c51461d27177d997e14c642fe18c11668fc09a3","analyzedAt":"2026-08-11T14:49:15.055Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}