grpc/grpc-go · warning
lrs: invalid load_reporting_interval
Error message
lrs: invalid load_reporting_interval: %v
What it means
Returned by recvFirstLoadStatsResponse when resp.LoadReportingInterval fails timestamp validation (lrs_stream.go:222). The LRS response must carry a valid duration; if it is absent or malformed the client cannot cadence its reports. Note: the message formats the previously-nil `err` variable, so the underlying CheckValid error is not surfaced in the text - the message is effectively a fixed string.
Solutions
- Server-side: ensure LoadStatsResponse.load_reporting_interval is set to a positive, valid duration (e.g. 1s-60s).
- Upgrade or patch the LRS server to a version known to populate the interval.
- If the server is Envoy, check the lrs_config / load_stats_config cluster settings.
Defensive patterns
Strategy: validation
Prevention
- Configure the LRS server to always send a positive load_reporting_interval.
- Integration-test the server response shape against the v3 LRS proto.
- If you control the server, add a unit test that the response always populates the interval.
When it happens
Trigger: Server sends a LoadStatsResponse where load_reporting_interval is unset or contains an invalid duration. internal := resp.GetLoadReportingInterval(); internal.CheckValid() != nil triggers the branch.
Common situations: Misconfigured LRS server omits the interval; server sends a zero or negative duration; proto schema mismatch causes the field to deserialize as zero.
Related errors
- lrs: unexpected message type %T
- lrsclient: failed to create transport for server identifier
- authority not found in the config for resource
- extauthz: empty grpc_service provided in config
- extauthz: failed to unmarshal config
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/2a87400f84da6ac1.
Report an issue: GitHub.
Appendix: source
Thrown at internal/xds/clients/lrsclient/lrs_stream.go:222
func (lrs *streamImpl) recvFirstLoadStatsResponse(stream clients.Stream) ([]string, time.Duration, error) {
r, err := stream.Recv()
if err != nil {
return nil, 0, fmt.Errorf("lrs: failed to receive first LoadStatsResponse: %v", err)
}
var resp v3lrspb.LoadStatsResponse
if err := proto.Unmarshal(r, &resp); err != nil {
if lrs.logger.V(2) {
lrs.logger.Infof("Failed to unmarshal response to LoadStatsResponse: %v", err)
}
return nil, time.Duration(0), fmt.Errorf("lrs: unexpected message type %T", r)
}
if lrs.logger.V(perRPCVerbosityLevel) {
lrs.logger.Infof("Received first LoadStatsResponse: %s", pretty.ToJSON(&resp))
}
internal := resp.GetLoadReportingInterval()
if internal.CheckValid() != nil {
return nil, 0, fmt.Errorf("lrs: invalid load_reporting_interval: %v", err)
}
loadReportingInterval := internal.AsDuration()
clusters := resp.Clusters
if resp.SendAllClusters {
// Return an empty slice to send stats for all clusters.
clusters = []string{}
}
return clusters, loadReportingInterval, nil
}
func (lrs *streamImpl) sendLoadStatsRequest(stream clients.Stream, loads []*loadData) error {
clusterStats := make([]*v3endpointpb.ClusterStats, 0, len(loads))
for _, sd := range loads {
droppedReqs := make([]*v3endpointpb.ClusterStats_DroppedRequests, 0, len(sd.drops))
for category, count := range sd.drops {
droppedReqs = append(droppedReqs, &v3endpointpb.ClusterStats_DroppedRequests{View on GitHub (pinned to 0c51461d27)