grpc/grpc-go · error
lrs: invalid load_reporting_interval: %v
Error message
lrs: invalid load_reporting_interval: %v
What it means
Returned when the first LoadStatsResponse unmarshals fine but resp.GetLoadReportingInterval().CheckValid() reports the duration as invalid (e.g. missing, negative seconds, or out-of-range). Note the message formats the stale `err` variable (nil at this point) rather than the CheckValid cause, which is a code defect, but the trigger is genuinely an invalid interval field from the server.
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 03255a9237)
Solutions
- Inspect the actual LoadStatsResponse the server emits (grpcurl / server logs) and confirm load_reporting_interval is a positive, valid duration.
- Fix the server-side LRS configuration to always set load_reporting_interval (Envoy/traffic-director normally send e.g. 10s/60s).
- If you control the server, ensure the duration is serialized via durationpb.New with a non-negative time.Duration.
Defensive patterns
Strategy: validation
Prevention
- Ensure the LRS server always sets a positive load_reporting_interval.
- Test the server's LRS response shape with grpcurl before client integration.
- Report the stale-err formatting defect upstream; the trigger itself is a server config issue.
When it happens
Trigger: An LRS server sends a LoadStatsResponse whose load_reporting_interval is unset, negative, or has an overflow; the client rejects it before entering the periodic sendLoads loop.
Common situations: Misconfigured or buggy control plane that omits load_reporting_interval, a custom LRS server returning a zero/negative duration, or a proto version skew where the field encoding differs.
Related errors
- lrsclient: failed to create transport for server identifier
- missing server_listener_resource_name_template in the bootst
- rls: failed to parse lookup_service_timeout in route lookup
- rls: failed to parse max_age in route lookup config %+v: %v
- rls: failed to parse staleAge in route lookup config %+v: %v
AI-assisted analysis of grpc/grpc-go@03255a9237 (2026-08-07).
Data as JSON: /api/errors/2a87400f84da6ac1.
Report an issue: GitHub.